Bug Summary

File:3rdparty/vboot/futility/cmd_gbb_utility.c
Warning:line 646, column 3
Value stored to 'gbb_base' is never read

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 cmd_gbb_utility.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 -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 futility/cmd_gbb_utility.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
6#include <errno(*__errno_location ()).h>
7#include <getopt.h>
8#include <inttypes.h>
9#include <stddef.h>
10#include <stdint.h>
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <sys/stat.h>
15#include <sys/types.h>
16#include <unistd.h>
17
18#include "flash_helpers.h"
19#include "futility.h"
20#include "updater.h"
21#include "updater_utils.h"
22#include "2gbb_flags.h"
23
24#ifdef USE_FLASHROM
25#define FLASH_ARG_HELP \
26 " --flash \tRead from and write to flash" \
27 ", ignore file arguments.\n"
28#define FLASH_MORE_HELP \
29 "In GET and SET mode, the following options modify the " \
30 "behaviour of flashing. Presence of any of these implies " \
31 "--flash.\n" \
32 SHARED_FLASH_ARGS_HELP \
33 "\n"
34#else
35#define FLASH_ARG_HELP
36#define FLASH_MORE_HELP
37#endif /* USE_FLASHROM */
38
39static void print_help(int argc, char *argv[])
40{
41 printf("\n"
42 "Usage: " MYNAME"futility" " %s [-g|-s|-c] [OPTIONS] "
43 "[image_file] [output_file]\n"
44 "\n"
45 "GET MODE:\n"
46 "-g, --get (default)\tGet (read) from image_file or flash, "
47 "with following options:\n"
48 FLASH_ARG_HELP
49 " --hwid \tReport hardware id (default).\n"
50 " --flags \tReport header flags.\n"
51 " --digest \tReport digest of hwid (>= v1.2)\n"
52 " -k, --rootkey=FILE \tFile name to export Root Key.\n"
53 " -b, --bmpfv=FILE \tFile name to export Bitmap FV.\n"
54 " -r --recoverykey=FILE\tFile name to export Recovery Key.\n"
55 " -e --explicit \tReport header flags by name.\n"
56 "\n"
57 "SET MODE:\n"
58 "-s, --set \tSet (write) to flash or file, "
59 "with following options:\n"
60 FLASH_ARG_HELP
61 " -o, --output=FILE \tNew file name for ouptput.\n"
62 " --hwid=HWID \tThe new hardware id to be changed.\n"
63 " --flags=FLAGS \tThe new (numeric) flags value or +/- diff value.\n"
64 " -k, --rootkey=FILE \tFile name of new Root Key.\n"
65 " -b, --bmpfv=FILE \tFile name of new Bitmap FV.\n"
66 " -r --recoverykey=FILE\tFile name of new Recovery Key.\n"
67 "\n"
68 "CREATE MODE:\n"
69 "-c, --create=hwid_size,rootkey_size,bmpfv_size,"
70 "recoverykey_size\n"
71 " \tCreate a GBB blob by given size list.\n\n"
72 FLASH_MORE_HELP
73 "SAMPLE:\n"
74 " %s -g image.bin\n"
75 " %s --set --hwid='New Model' -k key.bin"
76 " image.bin newimage.bin\n"
77 " %s -c 0x100,0x1000,0x03DE80,0x1000 gbb.blob\n\n"
78 "GBB Flags:\n"
79 " To get a developer-friendly device, try 0x18 (dev_mode boot_usb).\n"
80 " For early bringup development, try 0x40b9.\n",
81 argv[0], argv[0], argv[0], argv[0]);
82 for (vb2_gbb_flags_t flag = 1; flag; flag <<= 1) {
83 const char *name;
84 const char *description;
85 if (vb2_get_gbb_flag_description(flag, &name, &description) !=
86 VB2_SUCCESS)
87 break;
88 printf(" 0x%08x\t%s\n"
89 " \t%s\n",
90 flag, name, description);
91 }
92}
93
94enum {
95 OPT_HWID = 0x1000,
96 OPT_FLAGS,
97 OPT_DIGEST,
98 OPT_FLASH,
99 OPT_HELP,
100};
101
102/* Command line options */
103static struct option long_opts[] = {
104 SHARED_FLASH_ARGS_LONGOPTS
105 /* name has_arg *flag val */
106 {"get", 0, NULL((void*)0), 'g'},
107 {"set", 0, NULL((void*)0), 's'},
108 {"create", 1, NULL((void*)0), 'c'},
109 {"output", 1, NULL((void*)0), 'o'},
110 {"rootkey", 1, NULL((void*)0), 'k'},
111 {"bmpfv", 1, NULL((void*)0), 'b'},
112 {"recoverykey", 1, NULL((void*)0), 'r'},
113 {"hwid", 0, NULL((void*)0), OPT_HWID},
114 {"flags", 0, NULL((void*)0), OPT_FLAGS},
115 {"explicit", 0, NULL((void*)0), 'e'},
116 {"digest", 0, NULL((void*)0), OPT_DIGEST},
117 {"flash", 0, NULL((void*)0), OPT_FLASH},
118 {"help", 0, NULL((void*)0), OPT_HELP},
119 {NULL((void*)0), 0, NULL((void*)0), 0},
120};
121
122static const char *short_opts = ":gsc:o:k:b:r:e" SHARED_FLASH_ARGS_SHORTOPTS;
123
124/* Change the has_arg field of a long_opts entry */
125static void opt_has_arg(const char *name, int val)
126{
127 for (struct option *p = long_opts; p->name; p++) {
128 if (!strcmp(name, p->name)) {
129 p->has_arg = val;
130 break;
131 }
132 }
133}
134
135#define GBB_SEARCH_STRIDE4 4
136static struct vb2_gbb_header *FindGbbHeader(uint8_t *ptr, size_t size)
137{
138 size_t i;
139 struct vb2_gbb_header *tmp, *gbb_header = NULL((void*)0);
140 int count = 0;
141
142 for (i = 0; i <= size - GBB_SEARCH_STRIDE4; i += GBB_SEARCH_STRIDE4) {
143 if (memcmp(ptr + i, VB2_GBB_SIGNATURE"$GBB", VB2_GBB_SIGNATURE_SIZE4))
144 continue;
145
146 /* Found something. See if it's any good. */
147 tmp = (struct vb2_gbb_header *) (ptr + i);
148 if (futil_valid_gbb_header(tmp, size - i, NULL((void*)0)))
149 if (!count++)
150 gbb_header = tmp;
151 }
152
153 switch (count) {
154 case 0:
155 return NULL((void*)0);
156 case 1:
157 return gbb_header;
158 default:
159 ERROR("Multiple GBB headers found\n")fprintf(stderr, "ERROR: %s: " "Multiple GBB headers found\n",
__func__ )
;
160 return NULL((void*)0);
161 }
162}
163
164static uint8_t *create_gbb(const char *desc, off_t *sizeptr)
165{
166 char *param, *e = NULL((void*)0);
167 size_t size = EXPECTED_VB2_GBB_HEADER_SIZE128;
168 int i = 0;
169 /* Danger Will Robinson! four entries ==> four paramater blocks */
170 uint32_t val[] = { 0, 0, 0, 0 };
171
172 char *sizes = strdup(desc);
173 if (!sizes) {
174 ERROR("strdup() failed: %s\n", strerror(errno))fprintf(stderr, "ERROR: %s: " "strdup() failed: %s\n", __func__
, strerror((*__errno_location ())) )
;
175 return NULL((void*)0);
176 }
177
178 for (char *str = sizes; (param = strtok(str, ", ")) != NULL((void*)0); str = NULL((void*)0)) {
179 val[i] = (uint32_t) strtoul(param, &e, 0);
180 if (e && *e) {
181 ERROR("Invalid creation parameter: \"%s\"\n", param)fprintf(stderr, "ERROR: %s: " "Invalid creation parameter: \"%s\"\n"
, __func__, param )
;
182 free(sizes);
183 return NULL((void*)0);
184 }
185 size += val[i++];
186 if (i > ARRAY_SIZE(val)(sizeof(val) / sizeof((val)[0])))
187 break;
188 }
189
190 uint8_t *buf = (uint8_t *) calloc(1, size);
191 if (!buf) {
192 ERROR("Can't malloc %zu bytes: %s\n", size, strerror(errno))fprintf(stderr, "ERROR: %s: " "Can't malloc %zu bytes: %s\n",
__func__, size, strerror((*__errno_location ())) )
;
193 free(sizes);
194 return NULL((void*)0);
195 }
196 if (sizeptr)
197 *sizeptr = size;
198
199 struct vb2_gbb_header *gbb = (struct vb2_gbb_header *) buf;
200 memcpy(gbb->signature, VB2_GBB_SIGNATURE"$GBB", VB2_GBB_SIGNATURE_SIZE4);
201 gbb->major_version = VB2_GBB_MAJOR_VER1;
202 gbb->minor_version = VB2_GBB_MINOR_VER2;
203 gbb->header_size = EXPECTED_VB2_GBB_HEADER_SIZE128;
204 gbb->flags = 0;
205
206 i = EXPECTED_VB2_GBB_HEADER_SIZE128;
207 gbb->hwid_offset = i;
208 gbb->hwid_size = val[0];
209 i += val[0];
210
211 gbb->rootkey_offset = i;
212 gbb->rootkey_size = val[1];
213 i += val[1];
214
215 gbb->bmpfv_offset = i;
216 gbb->bmpfv_size = val[2];
217 i += val[2];
218
219 gbb->recovery_key_offset = i;
220 gbb->recovery_key_size = val[3];
221 i += val[1];
222
223 free(sizes);
224 return buf;
225}
226
227static uint8_t *read_entire_file(const char *filename, off_t *sizeptr)
228{
229 uint8_t *buf = NULL((void*)0);
230 struct stat sb;
231
232 FILE *fp = fopen(filename, "rb");
233 if (!fp) {
234 ERROR("Unable to open %s for reading: %s\n", filename,fprintf(stderr, "ERROR: %s: " "Unable to open %s for reading: %s\n"
, __func__, filename, strerror((*__errno_location ())) )
235 strerror(errno))fprintf(stderr, "ERROR: %s: " "Unable to open %s for reading: %s\n"
, __func__, filename, strerror((*__errno_location ())) )
;
236 goto fail;
237 }
238
239 if (fstat(fileno(fp), &sb)) {
240 ERROR("Can't fstat %s: %s\n", filename, strerror(errno))fprintf(stderr, "ERROR: %s: " "Can't fstat %s: %s\n", __func__
, filename, strerror((*__errno_location ())) )
;
241 goto fail;
242 }
243 if (sizeptr)
244 *sizeptr = sb.st_size;
245
246 buf = (uint8_t *) malloc(sb.st_size);
247 if (!buf) {
248 ERROR("Can't malloc %" PRIi64 " bytes: %s\n", sb.st_size,fprintf(stderr, "ERROR: %s: " "Can't malloc %" "l" "i" " bytes: %s\n"
, __func__, sb.st_size, strerror((*__errno_location ())) )
249 strerror(errno))fprintf(stderr, "ERROR: %s: " "Can't malloc %" "l" "i" " bytes: %s\n"
, __func__, sb.st_size, strerror((*__errno_location ())) )
;
250 goto fail;
251 }
252
253 if (1 != fread(buf, sb.st_size, 1, fp)) {
254 ERROR("Unable to read from %s: %s\n", filename,fprintf(stderr, "ERROR: %s: " "Unable to read from %s: %s\n",
__func__, filename, strerror((*__errno_location ())) )
255 strerror(errno))fprintf(stderr, "ERROR: %s: " "Unable to read from %s: %s\n",
__func__, filename, strerror((*__errno_location ())) )
;
256 goto fail;
257 }
258
259 if (fclose(fp)) {
260 ERROR("Unable to close %s: %s\n", filename, strerror(errno))fprintf(stderr, "ERROR: %s: " "Unable to close %s: %s\n", __func__
, filename, strerror((*__errno_location ())) )
;
261 fp = NULL((void*)0); /* Don't try to close it again */
262 goto fail;
263 }
264
265 return buf;
266
267fail:
268 if (buf)
269 free(buf);
270
271 if (fp && fclose(fp))
272 ERROR("Unable to close %s: %s\n", filename, strerror(errno))fprintf(stderr, "ERROR: %s: " "Unable to close %s: %s\n", __func__
, filename, strerror((*__errno_location ())) )
;
273 return NULL((void*)0);
274}
275
276static int read_from_file(const char *msg, const char *filename,
277 uint8_t *start, uint32_t size)
278{
279 struct stat sb;
280 size_t count;
281 int r = 0;
282
283 FILE *fp = fopen(filename, "rb");
284 if (!fp) {
285 r = errno(*__errno_location ());
286 ERROR("Unable to open %s for reading: %s\n", filename, strerror(r))fprintf(stderr, "ERROR: %s: " "Unable to open %s for reading: %s\n"
, __func__, filename, strerror(r) )
;
287 return r;
288 }
289
290 if (fstat(fileno(fp), &sb)) {
291 r = errno(*__errno_location ());
292 ERROR("Can't fstat %s: %s\n", filename, strerror(r))fprintf(stderr, "ERROR: %s: " "Can't fstat %s: %s\n", __func__
, filename, strerror(r) )
;
293 goto done_close;
294 }
295
296 if (sb.st_size > size) {
297 ERROR("File %s exceeds capacity (%" PRIu32 ")\n", filename, size)fprintf(stderr, "ERROR: %s: " "File %s exceeds capacity (%" "u"
")\n", __func__, filename, size )
;
298 r = -1;
299 goto done_close;
300 }
301
302 /* Wipe existing data. */
303 memset(start, 0, size);
304
305 /* It's okay if we read less than size. That's just the max. */
306 count = fread(start, 1, size, fp);
307 if (ferror(fp)) {
308 r = errno(*__errno_location ());
309 ERROR("Read %zu/%" PRIi64 " bytes from %s: %s\n", count,fprintf(stderr, "ERROR: %s: " "Read %zu/%" "l" "i" " bytes from %s: %s\n"
, __func__, count, sb.st_size, filename, strerror(r) )
310 sb.st_size, filename, strerror(r))fprintf(stderr, "ERROR: %s: " "Read %zu/%" "l" "i" " bytes from %s: %s\n"
, __func__, count, sb.st_size, filename, strerror(r) )
;
311 }
312
313done_close:
314 if (fclose(fp)) {
315 int e = errno(*__errno_location ());
316 ERROR("Unable to close %s: %s\n", filename, strerror(e))fprintf(stderr, "ERROR: %s: " "Unable to close %s: %s\n", __func__
, filename, strerror(e) )
;
317 if (!r)
318 r = e;
319 }
320
321 if (!r && msg)
322 printf(" - import %s from %s: success\n", msg, filename);
323
324 return r;
325}
326
327/* Read firmware from flash. */
328static uint8_t *read_from_flash(struct updater_config *cfg, off_t *filesize)
329{
330#ifdef USE_FLASHROM
331 /*
332 * Read the FMAP region as well, so that a subsequet write won't
333 * require another read of FMAP.
334 */
335 const char * const regions[] = {FMAP_RO_FMAP, FMAP_RO_GBB};
336 if (flashrom_read_image(&cfg->image_current, regions,
337 ARRAY_SIZE(regions)(sizeof(regions) / sizeof((regions)[0])), cfg->verbosity + 1))
338 return NULL((void*)0);
339 uint8_t *ret = cfg->image_current.data;
340 cfg->image_current.data = NULL((void*)0);
341 *filesize = cfg->image_current.size;
342 cfg->image_current.size = 0;
343 return ret;
344#else
345 return NULL((void*)0);
346#endif /* USE_FLASHROM */
347}
348
349/* Write firmware to flash. Takes ownership of inbuf and outbuf data. */
350static int write_to_flash(struct updater_config *cfg, uint8_t *outbuf,
351 off_t filesize)
352{
353#ifdef USE_FLASHROM
354 if (is_ap_write_protection_enabled(cfg)) {
355 ERROR("You must disable write protection before setting flags.\n")fprintf(stderr, "ERROR: %s: " "You must disable write protection before setting flags.\n"
, __func__ )
;
356 return -1;
357 }
358 cfg->image.data = outbuf;
359 cfg->image.size = filesize;
360
361 const char *sections[] = {FMAP_RO_GBB};
362 int ret = write_system_firmware(cfg, &cfg->image, sections,
363 ARRAY_SIZE(sections)(sizeof(sections) / sizeof((sections)[0])));
364
365 cfg->image.data = NULL((void*)0);
366 cfg->image.size = 0;
367 return ret;
368#else
369 return 1;
370#endif /* USE_FLASHROM */
371}
372
373static int parse_flag_value(const char *s, vb2_gbb_flags_t *val)
374{
375 int sign = 0;
376
377 if (!strlen(s))
378 return -1;
379
380 if (s[0] == '+')
381 sign = 1;
382 else if (s[0] == '-')
383 sign = 2;
384
385 const char *ss = !sign ? s : &s[1];
386 char *e = NULL((void*)0);
387 *val = strtoul(ss, &e, 0);
388 if (e && *e) {
389 ERROR("Invalid flags value: %s\n", ss)fprintf(stderr, "ERROR: %s: " "Invalid flags value: %s\n", __func__
, ss )
;
390 return -1;
391 }
392
393 return sign;
394}
395
396static int do_gbb(int argc, char *argv[])
397{
398 enum do_what_now { DO_GET, DO_SET, DO_CREATE } mode = DO_GET;
399 char *infile = NULL((void*)0);
400 char *outfile = NULL((void*)0);
401 char *opt_create = NULL((void*)0);
402 char *opt_rootkey = NULL((void*)0);
403 char *opt_bmpfv = NULL((void*)0);
404 char *opt_recoverykey = NULL((void*)0);
405 char *opt_hwid = NULL((void*)0);
406 char *opt_flags = NULL((void*)0);
407 bool_Bool sel_hwid = false0;
408 bool_Bool sel_digest = false0;
409 bool_Bool sel_flags = false0;
410 int explicit_flags = 0;
411 uint8_t *inbuf = NULL((void*)0);
412 off_t filesize;
413 uint8_t *outbuf = NULL((void*)0);
414 int i;
415 struct updater_config *cfg = NULL((void*)0);
416 struct updater_config_arguments args = {0};
417 int errorcnt = 0;
418
419
420 opterr = 0; /* quiet, you */
421 while ((i = getopt_long(argc, argv, short_opts, long_opts, 0)) != -1) {
422#ifdef USE_FLASHROM
423 if (handle_flash_argument(&args, i, optarg))
424 continue;
425#endif
426 switch (i) {
427 case 'g':
428 mode = DO_GET;
429 opt_has_arg("flags", 0);
430 opt_has_arg("hwid", 0);
431 break;
432 case 's':
433 mode = DO_SET;
434 opt_has_arg("flags", 1);
435 opt_has_arg("hwid", 1);
436 break;
437 case 'c':
438 mode = DO_CREATE;
439 opt_create = optarg;
440 break;
441 case 'o':
442 outfile = optarg;
443 break;
444 case 'k':
445 opt_rootkey = optarg;
446 break;
447 case 'b':
448 opt_bmpfv = optarg;
449 break;
450 case 'r':
451 opt_recoverykey = optarg;
452 break;
453 case OPT_HWID:
454 /* --hwid is optional: null might be okay */
455 opt_hwid = optarg;
456 sel_hwid = true1;
457 break;
458 case OPT_FLAGS:
459 /* --flags is optional: null might be okay */
460 opt_flags = optarg;
461 sel_flags = true1;
462 break;
463 case 'e':
464 sel_flags = true1;
465 explicit_flags = 1;
466 break;
467 case OPT_DIGEST:
468 sel_digest = true1;
469 break;
470 case OPT_FLASH:
471#ifndef USE_FLASHROM
472 ERROR("futility was built without flashrom support\n")fprintf(stderr, "ERROR: %s: " "futility was built without flashrom support\n"
, __func__ )
;
473 return 1;
474#endif
475 args.use_flash = 1;
476 break;
477 case OPT_HELP:
478 print_help(argc, argv);
479 return !!errorcnt;
480
481 case '?':
482 errorcnt++;
483 if (optopt)
484 ERROR("Unrecognized option: -%c\n", optopt)fprintf(stderr, "ERROR: %s: " "Unrecognized option: -%c\n", __func__
, optopt )
;
485 else if (argv[optind - 1])
486 ERROR("Unrecognized option (possibly \"%s\")\n",fprintf(stderr, "ERROR: %s: " "Unrecognized option (possibly \"%s\")\n"
, __func__, argv[optind - 1] )
487 argv[optind - 1])fprintf(stderr, "ERROR: %s: " "Unrecognized option (possibly \"%s\")\n"
, __func__, argv[optind - 1] )
;
488 else
489 ERROR("Unrecognized option\n")fprintf(stderr, "ERROR: %s: " "Unrecognized option\n", __func__
)
;
490 break;
491 case ':':
492 errorcnt++;
493 if (argv[optind - 1])
494 ERROR("Missing argument to -%c (%s)\n", optopt,fprintf(stderr, "ERROR: %s: " "Missing argument to -%c (%s)\n"
, __func__, optopt, argv[optind - 1] )
495 argv[optind - 1])fprintf(stderr, "ERROR: %s: " "Missing argument to -%c (%s)\n"
, __func__, optopt, argv[optind - 1] )
;
496 else
497 ERROR("Missing argument to -%c\n", optopt)fprintf(stderr, "ERROR: %s: " "Missing argument to -%c\n", __func__
, optopt )
;
498 break;
499 default:
500 errorcnt++;
501 ERROR("While parsing options\n")fprintf(stderr, "ERROR: %s: " "While parsing options\n", __func__
)
;
502 }
503 }
504
505 /* Problems? */
506 if (errorcnt) {
507 print_help(argc, argv);
508 return 1;
509 }
510
511 if (args.use_flash) {
512 if (setup_flash(&cfg, &args)) {
513 ERROR("While preparing flash\n")fprintf(stderr, "ERROR: %s: " "While preparing flash\n", __func__
)
;
514 return 1;
515 }
516 }
517
518 /* Now try to do something */
519 switch (mode) {
520 case DO_GET:
521 if (args.use_flash) {
522 inbuf = read_from_flash(cfg, &filesize);
523 } else {
524 if (argc - optind < 1) {
525 ERROR("Missing input filename\n")fprintf(stderr, "ERROR: %s: " "Missing input filename\n", __func__
)
;
526 print_help(argc, argv);
527 errorcnt++;
528 break;
529 }
530 infile = argv[optind++];
531 inbuf = read_entire_file(infile, &filesize);
532 }
533 if (!inbuf) {
534 errorcnt++;
535 break;
536 }
537
538 /* With no args, show the HWID */
539 if (!opt_rootkey && !opt_bmpfv && !opt_recoverykey
540 && !sel_flags && !sel_digest)
541 sel_hwid = true1;
542
543 struct vb2_gbb_header *gbb = FindGbbHeader(inbuf, filesize);
544 if (!gbb) {
545 ERROR("No GBB found in %s\n", infile)fprintf(stderr, "ERROR: %s: " "No GBB found in %s\n", __func__
, infile )
;
546 errorcnt++;
547 break;
548 }
549 uint8_t *gbb_base = (uint8_t *) gbb;
550
551 /* Get the stuff */
552 if (sel_hwid)
553 printf("hardware_id: %s\n",
554 gbb->hwid_size ? (char *)(gbb_base +
555 gbb->
556 hwid_offset) : "");
557 if (sel_digest)
558 print_hwid_digest(gbb, "digest: ");
559
560 if (sel_flags)
561 printf("flags: 0x%08x\n", gbb->flags);
562 if (opt_rootkey)
563 if (write_to_file(" - exported root_key to file:",
564 opt_rootkey,
565 gbb_base + gbb->rootkey_offset,
566 gbb->rootkey_size)) {
567 errorcnt++;
568 break;
569 }
570 if (opt_bmpfv)
571 if (write_to_file(
572 " - exported bmp_fv to file:", opt_bmpfv,
573 gbb_base + gbb->bmpfv_offset,
574 gbb->bmpfv_size)) {
575 errorcnt++;
576 break;
577 }
578 if (opt_recoverykey)
579 if (write_to_file(" - exported recovery_key to file:",
580 opt_recoverykey,
581 gbb_base + gbb->recovery_key_offset,
582 gbb->recovery_key_size)) {
583 errorcnt++;
584 break;
585 }
586 if (explicit_flags) {
587 vb2_gbb_flags_t remaining_flags = gbb->flags;
588 while (remaining_flags) {
589 vb2_gbb_flags_t lsb_flag =
590 remaining_flags & -remaining_flags;
591 remaining_flags &= ~lsb_flag;
592 const char *name;
593 const char *description;
594 if (vb2_get_gbb_flag_description(
595 lsb_flag, &name, &description) ==
596 VB2_SUCCESS) {
597 printf("%s\n", name);
598 } else {
599 printf("unknown set flag: 0x%08x\n",
600 lsb_flag);
601 }
602 }
603 }
604 break;
605
606 case DO_SET:
607 if (args.use_flash) {
608 inbuf = read_from_flash(cfg, &filesize);
609 } else {
610 if (argc - optind < 1) {
611 ERROR("Missing input filename\n")fprintf(stderr, "ERROR: %s: " "Missing input filename\n", __func__
)
;
612 print_help(argc, argv);
613 errorcnt++;
614 break;
615 }
616 infile = argv[optind++];
617 inbuf = read_entire_file(infile, &filesize);
618 if (!outfile)
619 outfile = (argc - optind < 1) ? infile
620 : argv[optind++];
621 }
622 if (!inbuf) {
623 errorcnt++;
624 break;
625 }
626
627 if (sel_hwid && !opt_hwid) {
628 ERROR("Missing new HWID value\n")fprintf(stderr, "ERROR: %s: " "Missing new HWID value\n", __func__
)
;
629 print_help(argc, argv);
630 errorcnt++;
631 break;
632 }
633 if (sel_flags && (!opt_flags || !*opt_flags)) {
634 ERROR("Missing new flags value\n")fprintf(stderr, "ERROR: %s: " "Missing new flags value\n", __func__
)
;
635 print_help(argc, argv);
636 errorcnt++;
637 break;
638 }
639
640 gbb = FindGbbHeader(inbuf, filesize);
641 if (!gbb) {
642 ERROR("No GBB found in %s\n", infile)fprintf(stderr, "ERROR: %s: " "No GBB found in %s\n", __func__
, infile )
;
643 errorcnt++;
644 break;
645 }
646 gbb_base = (uint8_t *) gbb;
Value stored to 'gbb_base' is never read
647
648 outbuf = (uint8_t *) malloc(filesize);
649 if (!outbuf) {
650 ERROR("Can't malloc %" PRIi64 " bytes: %s\n", filesize,fprintf(stderr, "ERROR: %s: " "Can't malloc %" "l" "i" " bytes: %s\n"
, __func__, filesize, strerror((*__errno_location ())) )
651 strerror(errno))fprintf(stderr, "ERROR: %s: " "Can't malloc %" "l" "i" " bytes: %s\n"
, __func__, filesize, strerror((*__errno_location ())) )
;
652 errorcnt++;
653 break;
654 }
655
656 /* Switch pointers to outbuf */
657 memcpy(outbuf, inbuf, filesize);
658 gbb = FindGbbHeader(outbuf, filesize);
659 if (!gbb) {
660 ERROR("INTERNAL ERROR: No GBB found in outbuf\n")fprintf(stderr, "ERROR: %s: " "INTERNAL ERROR: No GBB found in outbuf\n"
, __func__ )
;
661 errorcnt++;
662 break;
663 }
664 gbb_base = (uint8_t *) gbb;
665
666 if (opt_hwid) {
667 if (strlen(opt_hwid) + 1 > gbb->hwid_size) {
668 ERROR("null-terminated HWID exceeds capacity (%d)\n",fprintf(stderr, "ERROR: %s: " "null-terminated HWID exceeds capacity (%d)\n"
, __func__, gbb->hwid_size )
669 gbb->hwid_size)fprintf(stderr, "ERROR: %s: " "null-terminated HWID exceeds capacity (%d)\n"
, __func__, gbb->hwid_size )
;
670 errorcnt++;
671 break;
672 }
673 /* Wipe data before writing new value. */
674 memset(gbb_base + gbb->hwid_offset, 0,
675 gbb->hwid_size);
676 strcpy((char *)(gbb_base + gbb->hwid_offset),
677 opt_hwid);
678 update_hwid_digest(gbb);
679 }
680
681 if (opt_flags) {
682 vb2_gbb_flags_t val;
683 const int flag_sign = parse_flag_value(opt_flags, &val);
684 if (flag_sign < 0) {
685 errorcnt++;
686 break;
687 }
688 if (flag_sign > 0)
689 /* flag_sign := 1 => +ve and flag_sign := 2 => -ve. */
690 gbb->flags = flag_sign == 1 ? (gbb->flags | val) : (gbb->flags & ~val);
691 else
692 gbb->flags = val;
693 }
694
695 if (opt_rootkey) {
696 if (read_from_file("root_key", opt_rootkey,
697 gbb_base + gbb->rootkey_offset,
698 gbb->rootkey_size)) {
699 errorcnt++;
700 break;
701 }
702 }
703 if (opt_bmpfv)
704 if (read_from_file("bmp_fv", opt_bmpfv,
705 gbb_base + gbb->bmpfv_offset,
706 gbb->bmpfv_size)) {
707 errorcnt++;
708 break;
709 }
710 if (opt_recoverykey)
711 if (read_from_file("recovery_key", opt_recoverykey,
712 gbb_base + gbb->recovery_key_offset,
713 gbb->recovery_key_size)) {
714 errorcnt++;
715 break;
716 }
717
718 /* Write it out if there are no problems. */
719 if (!errorcnt) {
720 if (args.use_flash) {
721 if (write_to_flash(cfg, outbuf, filesize)) {
722 errorcnt++;
723 break;
724 }
725 } else if (write_to_file(
726 "successfully saved new image to:",
727 outfile, outbuf, filesize)) {
728 errorcnt++;
729 break;
730 }
731 }
732 break;
733
734 case DO_CREATE:
735 if (!outfile) {
736 if (argc - optind < 1) {
737 ERROR("Missing output filename\n")fprintf(stderr, "ERROR: %s: " "Missing output filename\n", __func__
)
;
738 print_help(argc, argv);
739 errorcnt++;
740 break;
741 }
742 outfile = argv[optind++];
743 }
744 /* Parse the creation args */
745 outbuf = create_gbb(opt_create, &filesize);
746 if (!outbuf) {
747 ERROR("Unable to parse creation spec (%s)\n", opt_create)fprintf(stderr, "ERROR: %s: " "Unable to parse creation spec (%s)\n"
, __func__, opt_create )
;
748 print_help(argc, argv);
749 errorcnt++;
750 break;
751 }
752 if (!errorcnt)
753 if (write_to_file("successfully created new GBB to:",
754 outfile, outbuf, filesize)) {
755 errorcnt++;
756 break;
757 }
758 break;
759 }
760
761 if (args.use_flash)
762 teardown_flash(cfg);
763 if (inbuf)
764 free(inbuf);
765 if (outbuf)
766 free(outbuf);
767 return !!errorcnt;
768}
769
770DECLARE_FUTIL_COMMAND(gbb, do_gbb, VBOOT_VERSION_ALL,const struct futil_cmd_t __cmd_gbb = { .name = "gbb", .handler
= do_gbb, .version = VBOOT_VERSION_ALL, .shorthelp = "Manipulate the Google Binary Block (GBB)"
, }
771 "Manipulate the Google Binary Block (GBB)")const struct futil_cmd_t __cmd_gbb = { .name = "gbb", .handler
= do_gbb, .version = VBOOT_VERSION_ALL, .shorthelp = "Manipulate the Google Binary Block (GBB)"
, }
;
772DECLARE_FUTIL_COMMAND(gbb_utility, do_gbb, VBOOT_VERSION_ALL,const struct futil_cmd_t __cmd_gbb_utility = { .name = "gbb_utility"
, .handler = do_gbb, .version = VBOOT_VERSION_ALL, .shorthelp
= "Legacy name for `gbb` command", }
773 "Legacy name for `gbb` command")const struct futil_cmd_t __cmd_gbb_utility = { .name = "gbb_utility"
, .handler = do_gbb, .version = VBOOT_VERSION_ALL, .shorthelp
= "Legacy name for `gbb` command", }
;