Bug Summary

File:3rdparty/vboot/host/lib/util_misc.c
Warning:line 160, column 2
Argument to free() is offset by 4 bytes from the start of memory allocated by malloc()

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name util_misc.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/vboot -resource-dir /opt/xgcc/lib/clang/17 -D CHROMEOS_ENVIRONMENT -D EC_EFS=0 -D EXTERNAL_TPM_CLEAR_REQUEST=0 -D _GNU_SOURCE -D _FILE_OFFSET_BITS=64 -D HAVE_EXECINFO_H -D HAVE_NSS -I /usr/include/nss -I /usr/include/nspr -I firmware/include -I firmware/lib/include -I firmware/lib/cgptlib/include -I firmware/lib/tpm_lite/include -I firmware/2lib/include -I host/include -I host/lib/include -I host/lib21/include -internal-isystem /opt/xgcc/lib/clang/17/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -source-date-epoch 1714465709 -Os -Wno-deprecated-declarations -Wno-trigraphs -Wwrite-strings -Wno-format-security -Wno-address-of-packed-member -Wno-unknown-warning -Wno-error=deprecated-declarations -std=gnu11 -fconst-strings -fdebug-compilation-dir=/home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/vboot -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-opt-analyze-headers -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /cb-build/coreboot_scanbuild.0/sharedutils-scanbuildtmp/2024-05-02-073004-2299942-1 -x c host/lib/util_misc.c
1/* Copyright 2014 The ChromiumOS Authors
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 *
5 * Miscellaneous functions for userspace vboot utilities.
6 */
7
8#include <openssl/bn.h>
9#include <openssl/rsa.h>
10
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <unistd.h>
15
16#include "2common.h"
17#include "2sha.h"
18#include "2sysincludes.h"
19#include "host_common.h"
20#include "host_key21.h"
21#include "host_p11.h"
22#include "openssl_compat.h"
23#include "util_misc.h"
24
25const char *packed_key_sha1_string(const struct vb2_packed_key *key)
26{
27 uint8_t *buf = ((uint8_t *)key) + key->key_offset;
28 uint32_t buflen = key->key_size;
29 struct vb2_hash hash;
30 static char dest[VB2_SHA1_DIGEST_SIZE20 * 2 + 1];
31
32 vb2_hash_calculate(false0, buf, buflen, VB2_HASH_SHA1, &hash);
33
34 char *dnext = dest;
35 int i;
36 for (i = 0; i < sizeof(hash.sha1); i++)
37 dnext += sprintf(dnext, "%02x", hash.sha1[i]);
38
39 return dest;
40}
41
42const char *private_key_sha1_string(const struct vb2_private_key *key)
43{
44 uint8_t *buf;
45 uint32_t buflen;
46 struct vb2_hash hash;
47 static char dest[VB2_SHA1_DIGEST_SIZE20 * 2 + 1];
48
49 if (!key->rsa_private_key ||
50 vb_keyb_from_rsa(key->rsa_private_key, &buf, &buflen)) {
51 return "<error>";
52 }
53
54 vb2_hash_calculate(false0, buf, buflen, VB2_HASH_SHA1, &hash);
55
56 char *dnext = dest;
57 int i;
58 for (i = 0; i < sizeof(hash.sha1); i++)
59 dnext += sprintf(dnext, "%02x", hash.sha1[i]);
60
61 free(buf);
62 return dest;
63}
64
65static int vb_keyb_from_modulus(const BIGNUM *rsa_private_key_n, uint32_t modulus_size,
66 uint8_t **keyb_data, uint32_t *keyb_size)
67{
68 uint32_t i;
69 uint32_t nwords = modulus_size / 4;
70 BIGNUM *N = NULL((void*)0);
71 BIGNUM *Big1 = NULL((void*)0), *Big2 = NULL((void*)0), *Big32 = NULL((void*)0), *BigMinus1 = NULL((void*)0);
72 BIGNUM *B = NULL((void*)0);
73 BIGNUM *N0inv = NULL((void*)0), *R = NULL((void*)0), *RR = NULL((void*)0);
74 BIGNUM *RRTemp = NULL((void*)0), *NnumBits = NULL((void*)0);
75 BIGNUM *n = NULL((void*)0), *rr = NULL((void*)0);
76 BN_CTX *bn_ctx = BN_CTX_new();
77 uint32_t n0invout;
78 uint32_t bufsize;
79 uint32_t *outbuf;
80 int retval = 1;
81
82 bufsize = (2 + nwords + nwords) * sizeof(uint32_t);
83 outbuf = malloc(bufsize);
84 if (!outbuf)
6
Assuming 'outbuf' is non-null
7
Taking false branch
85 goto done;
86
87 *keyb_data = (uint8_t *)outbuf;
88 *keyb_size = bufsize;
89
90 *outbuf++ = nwords;
91
92 /* Initialize BIGNUMs */
93#define NEW_BIGNUM(x) do { x = BN_new(); if (!x) goto done; } while (0)
94 NEW_BIGNUM(N);
8
Assuming 'N' is null
9
Taking true branch
10
Control jumps to line 160
95 NEW_BIGNUM(Big1);
96 NEW_BIGNUM(Big2);
97 NEW_BIGNUM(Big32);
98 NEW_BIGNUM(BigMinus1);
99 NEW_BIGNUM(N0inv);
100 NEW_BIGNUM(R);
101 NEW_BIGNUM(RR);
102 NEW_BIGNUM(RRTemp);
103 NEW_BIGNUM(NnumBits);
104 NEW_BIGNUM(n);
105 NEW_BIGNUM(rr);
106 NEW_BIGNUM(B);
107#undef NEW_BIGNUM
108
109 BN_copy(N, rsa_private_key_n);
110 BN_set_word(Big1, 1L);
111 BN_set_word(Big2, 2L);
112 BN_set_word(Big32, 32L);
113 BN_sub(BigMinus1, Big1, Big2);
114
115 BN_exp(B, Big2, Big32, bn_ctx); /* B = 2^32 */
116
117 /* Calculate and output N0inv = -1 / N[0] mod 2^32 */
118 BN_mod_inverse(N0inv, N, B, bn_ctx);
119 BN_sub(N0inv, B, N0inv);
120 n0invout = BN_get_word(N0inv);
121
122 *outbuf++ = n0invout;
123
124 /* Calculate R = 2^(# of key bits) */
125 BN_set_word(NnumBits, BN_num_bits(N));
126 BN_exp(R, Big2, NnumBits, bn_ctx);
127
128 /* Calculate RR = R^2 mod N */
129 BN_copy(RR, R);
130 BN_mul(RRTemp, RR, R, bn_ctx);
131 BN_mod(RR, RRTemp, N, bn_ctx)BN_div(((void*)0),(RR),(RRTemp),(N),(bn_ctx));
132
133
134 /* Write out modulus as little endian array of integers. */
135 for (i = 0; i < nwords; ++i) {
136 uint32_t nout;
137
138 BN_mod(n, N, B, bn_ctx)BN_div(((void*)0),(n),(N),(B),(bn_ctx)); /* n = N mod B */
139 nout = BN_get_word(n);
140 *outbuf++ = nout;
141
142 BN_rshift(N, N, 32); /* N = N/B */
143 }
144
145 /* Write R^2 as little endian array of integers. */
146 for (i = 0; i < nwords; ++i) {
147 uint32_t rrout;
148
149 BN_mod(rr, RR, B, bn_ctx)BN_div(((void*)0),(rr),(RR),(B),(bn_ctx)); /* rr = RR mod B */
150 rrout = BN_get_word(rr);
151 *outbuf++ = rrout;
152
153 BN_rshift(RR, RR, 32); /* RR = RR/B */
154 }
155
156 outbuf = NULL((void*)0);
157 retval = 0;
158
159done:
160 free(outbuf);
11
Argument to free() is offset by 4 bytes from the start of memory allocated by malloc()
161 /* Free BIGNUMs. */
162 BN_free(Big1);
163 BN_free(Big2);
164 BN_free(Big32);
165 BN_free(BigMinus1);
166 BN_free(N0inv);
167 BN_free(R);
168 BN_free(RRTemp);
169 BN_free(NnumBits);
170 BN_free(n);
171 BN_free(rr);
172
173 return retval;
174}
175
176static int vb_keyb_from_p11_key(struct pkcs11_key *p11_key, uint8_t **keyb_data,
177 uint32_t *keyb_size)
178{
179 int ret = 1;
180 uint32_t modulus_size = 0;
181 BIGNUM *N = NULL((void*)0);
182 uint8_t *modulus = pkcs11_get_modulus(p11_key, &modulus_size);
183 if (!modulus) {
184 fprintf(stderrstderr, "Failed to get modulus from PKCS#11 key\n");
185 goto done;
186 }
187
188 N = BN_bin2bn(modulus, modulus_size, NULL((void*)0));
189 if (!N) {
190 fprintf(stderrstderr, "Failed to call BN_bin2bn()\n");
191 goto done;
192 }
193 ret = vb_keyb_from_modulus(N, modulus_size, keyb_data, keyb_size);
194done:
195 BN_free(N);
196 free(modulus);
197 return ret;
198}
199
200int vb_keyb_from_rsa(struct rsa_st *rsa_private_key, uint8_t **keyb_data, uint32_t *keyb_size)
201{
202 const BIGNUM *N;
203 RSA_get0_key(rsa_private_key, &N, NULL((void*)0), NULL((void*)0));
204 if (!N) {
3
Assuming 'N' is non-null
4
Taking false branch
205 fprintf(stderrstderr, "Failed to get N from RSA private key\n");
206 return 1;
207 }
208 return vb_keyb_from_modulus(N, RSA_size(rsa_private_key), keyb_data, keyb_size);
5
Calling 'vb_keyb_from_modulus'
209}
210
211int vb_keyb_from_private_key(struct vb2_private_key *private_key, uint8_t **keyb_data,
212 uint32_t *keyb_size)
213{
214 switch (private_key->key_location) {
1
Control jumps to 'case PRIVATE_KEY_LOCAL:' at line 217
215 case PRIVATE_KEY_P11:
216 return vb_keyb_from_p11_key(private_key->p11_key, keyb_data, keyb_size);
217 case PRIVATE_KEY_LOCAL:
218 return vb_keyb_from_rsa(private_key->rsa_private_key, keyb_data, keyb_size);
2
Calling 'vb_keyb_from_rsa'
219 }
220 return 1;
221}
222
223enum vb2_signature_algorithm vb2_get_sig_alg(uint32_t exp, uint32_t bits)
224{
225 switch (exp) {
226 case RSA_30x3L:
227 switch (bits) {
228 case 2048:
229 return VB2_SIG_RSA2048_EXP3;
230 case 3072:
231 return VB2_SIG_RSA3072_EXP3;
232 }
233 break;
234 case RSA_F40x10001L:
235 switch (bits) {
236 case 1024:
237 return VB2_SIG_RSA1024;
238 case 2048:
239 return VB2_SIG_RSA2048;
240 case 4096:
241 return VB2_SIG_RSA4096;
242 case 8192:
243 return VB2_SIG_RSA8192;
244 }
245 }
246
247 /* no clue */
248 return VB2_SIG_INVALID;
249}