diff options
author | Jae Hoon Kim <kimjae@chromium.org> | 2023-03-24 22:24:06 +0000 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2023-03-28 07:04:05 +0000 |
commit | 6d1c48e3179056d965edfdd630a9dd6cda12f14b (patch) | |
tree | 63cb681341649c7f88ebb14ef846db8e7e126435 | |
parent | 64e9aec36289ade7e7372e41a4e599d86948a97a (diff) | |
download | vboot-6d1c48e3179056d965edfdd630a9dd6cda12f14b.tar.gz |
cgpt: Add support for error counter (verity)
.. so platform side daemons/process can initiate getting/setting the
error counter (verity) attribute from GPT partitions of CrOS kernels.
```
$> cgpt show <IMAGE>
405504 65536 2 Label: "KERN-A"
Type: ChromeOS kernel
UUID: 0394A807-59A0-A84C-A443-BC3C555C8842
Attr: priority=15 tries=15 successful=1 error_counter=0
...
$> cgpt add -E1 -i2 <IMAGE>
$> cgpt show <IMAGE>
405504 65536 2 Label: "KERN-A"
Type: ChromeOS kernel
UUID: 0394A807-59A0-A84C-A443-BC3C555C8842
Attr: priority=15 tries=15 successful=1 error_counter=1
...
$> cgpt add -E0 -i2 <IMAGE>
$> cgpt show <IMAGE>
405504 65536 2 Label: "KERN-A"
Type: ChromeOS kernel
UUID: 0394A807-59A0-A84C-A443-BC3C555C8842
Attr: priority=15 tries=15 successful=1 error_counter=0
...
```
BUG=b:274539529
BRANCH=None
TEST=emerge vboot_reference
TEST=comment above
Change-Id: Ib0904378fba8219a3631278c66b7317fd86ea9d8
Signed-off-by: Jae Hoon Kim <kimjae@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/4370744
Reviewed-by: Julius Werner <jwerner@chromium.org>
-rw-r--r-- | cgpt/cgpt.h | 3 | ||||
-rw-r--r-- | cgpt/cgpt_add.c | 5 | ||||
-rw-r--r-- | cgpt/cgpt_common.c | 15 | ||||
-rw-r--r-- | cgpt/cgpt_show.c | 7 | ||||
-rw-r--r-- | cgpt/cmd_add.c | 9 | ||||
-rw-r--r-- | firmware/include/gpt_misc.h | 2 | ||||
-rw-r--r-- | firmware/lib/cgptlib/cgptlib_internal.c | 14 | ||||
-rw-r--r-- | firmware/lib/cgptlib/include/cgptlib_internal.h | 8 | ||||
-rw-r--r-- | host/include/cgpt_params.h | 2 | ||||
-rw-r--r-- | tests/cgptlib_test.c | 13 |
10 files changed, 73 insertions, 5 deletions
diff --git a/cgpt/cgpt.h b/cgpt/cgpt.h index 17f2ab09..b584dc02 100644 --- a/cgpt/cgpt.h +++ b/cgpt/cgpt.h @@ -150,6 +150,9 @@ int GetTries(struct drive *drive, int secondary, uint32_t entry_index); void SetSuccessful(struct drive *drive, int secondary, uint32_t entry_index, int success); int GetSuccessful(struct drive *drive, int secondary, uint32_t entry_index); +void SetErrorCounter(struct drive *drive, int secondary, uint32_t entry_index, + int error_counter); +int GetErrorCounter(struct drive *drive, int secondary, uint32_t entry_index); void SetRaw(struct drive *drive, int secondary, uint32_t entry_index, uint32_t raw); diff --git a/cgpt/cgpt_add.c b/cgpt/cgpt_add.c index 8097d337..16fe6caa 100644 --- a/cgpt/cgpt_add.c +++ b/cgpt/cgpt_add.c @@ -29,6 +29,8 @@ static void PrintCgptAddParams(const CgptAddParams *params) { GuidToStr(¶ms->unique_guid, tmp, sizeof(tmp)); fprintf(stderr, "-u %s ", tmp); } + if (params->set_error_counter) + fprintf(stderr, "-E %d ", params->error_counter); if (params->set_successful) fprintf(stderr, "-S %d ", params->successful); if (params->set_tries) @@ -84,6 +86,8 @@ static int SetEntryAttributes(struct drive *drive, if (params->set_raw) { SetRaw(drive, PRIMARY, index, params->raw_value); } else { + if (params->set_error_counter) + SetErrorCounter(drive, PRIMARY, index, params->error_counter); if (params->set_successful) SetSuccessful(drive, PRIMARY, index, params->successful); if (params->set_tries) @@ -237,6 +241,7 @@ int CgptGetPartitionDetails(CgptAddParams *params) { memcpy(¶ms->unique_guid, &entry->unique, sizeof(Guid)); params->raw_value = entry->attrs.fields.gpt_att; + params->error_counter = GetErrorCounter(&drive, PRIMARY, index); params->successful = GetSuccessful(&drive, PRIMARY, index); params->tries = GetTries(&drive, PRIMARY, index); params->priority = GetPriority(&drive, PRIMARY, index); diff --git a/cgpt/cgpt_common.c b/cgpt/cgpt_common.c index 071d31a5..dde67b71 100644 --- a/cgpt/cgpt_common.c +++ b/cgpt/cgpt_common.c @@ -838,6 +838,21 @@ int GetSuccessful(struct drive *drive, int secondary, uint32_t entry_index) { return GetEntrySuccessful(entry); } +void SetErrorCounter(struct drive *drive, int secondary, uint32_t entry_index, + int error_counter) { + require(error_counter >= 0 && + error_counter <= CGPT_ATTRIBUTE_MAX_ERROR_COUNTER); + GptEntry *entry; + entry = GetEntry(&drive->gpt, secondary, entry_index); + SetEntryErrorCounter(entry, error_counter); +} + +int GetErrorCounter(struct drive *drive, int secondary, uint32_t entry_index) { + GptEntry *entry; + entry = GetEntry(&drive->gpt, secondary, entry_index); + return GetEntryErrorCounter(entry); +} + void SetRaw(struct drive *drive, int secondary, uint32_t entry_index, uint32_t raw) { GptEntry *entry; diff --git a/cgpt/cgpt_show.c b/cgpt/cgpt_show.c index fa22c871..7d481e95 100644 --- a/cgpt/cgpt_show.c +++ b/cgpt/cgpt_show.c @@ -133,9 +133,12 @@ void EntryDetails(GptEntry *entry, uint32_t index, int raw) { int priority = (entry->attrs.fields.gpt_att & CGPT_ATTRIBUTE_PRIORITY_MASK) >> CGPT_ATTRIBUTE_PRIORITY_OFFSET; + int error_counter = (entry->attrs.fields.gpt_att & + CGPT_ATTRIBUTE_ERROR_COUNTER_MASK) >> + CGPT_ATTRIBUTE_ERROR_COUNTER_OFFSET; clen = snprintf(contents, sizeof(contents), - "priority=%d tries=%d successful=%d ", - priority, tries, successful); + "priority=%d tries=%d successful=%d error_counter=%d ", + priority, tries, successful, error_counter); } if (entry->attrs.fields.required) { diff --git a/cgpt/cmd_add.c b/cgpt/cmd_add.c index 5a752c76..3411925a 100644 --- a/cgpt/cmd_add.c +++ b/cgpt/cmd_add.c @@ -25,6 +25,7 @@ static void Usage(void) " -t GUID Partition Type GUID\n" " -u GUID Partition Unique ID\n" " -l LABEL Label\n" + " -E NUM set Error counter flag (0|1)\n" " -S NUM set Successful flag (0|1)\n" " -T NUM set Tries flag (0-15)\n" " -P NUM set Priority flag (0-15)\n" @@ -48,7 +49,7 @@ int cmd_add(int argc, char *argv[]) { char *e = 0; opterr = 0; // quiet, you - while ((c=getopt(argc, argv, ":hi:b:s:t:u:l:S:T:P:R:B:A:D:")) != -1) + while ((c=getopt(argc, argv, ":hi:b:s:t:u:l:E:S:T:P:R:B:A:D:")) != -1) { switch (c) { @@ -88,6 +89,12 @@ int cmd_add(int argc, char *argv[]) { case 'l': params.label = optarg; break; + case 'E': + params.set_error_counter = 1; + params.error_counter = (uint32_t)strtoul(optarg, &e, 0); + errorcnt += check_int_parse(c, e); + errorcnt += check_int_limit(c, params.error_counter, 0, 1); + break; case 'S': params.set_successful = 1; params.successful = (uint32_t)strtoul(optarg, &e, 0); diff --git a/firmware/include/gpt_misc.h b/firmware/include/gpt_misc.h index d97f2fc9..776ed230 100644 --- a/firmware/include/gpt_misc.h +++ b/firmware/include/gpt_misc.h @@ -206,11 +206,13 @@ int GetEntryLegacyBoot(const GptEntry *e); int GetEntrySuccessful(const GptEntry *e); int GetEntryPriority(const GptEntry *e); int GetEntryTries(const GptEntry *e); +int GetEntryErrorCounter(const GptEntry *e); void SetEntryRequired(GptEntry *e, int required); void SetEntryLegacyBoot(GptEntry *e, int legacy_boot); void SetEntrySuccessful(GptEntry *e, int successful); void SetEntryPriority(GptEntry *e, int priority); void SetEntryTries(GptEntry *e, int tries); +void SetEntryErrorCounter(GptEntry *e, int error_counter); #ifdef __cplusplus } diff --git a/firmware/lib/cgptlib/cgptlib_internal.c b/firmware/lib/cgptlib/cgptlib_internal.c index 347d46e0..ab01d5d9 100644 --- a/firmware/lib/cgptlib/cgptlib_internal.c +++ b/firmware/lib/cgptlib/cgptlib_internal.c @@ -405,6 +405,12 @@ int GetEntryTries(const GptEntry *e) CGPT_ATTRIBUTE_TRIES_OFFSET; } +int GetEntryErrorCounter(const GptEntry *e) +{ + return (e->attrs.fields.gpt_att & CGPT_ATTRIBUTE_ERROR_COUNTER_MASK) >> + CGPT_ATTRIBUTE_ERROR_COUNTER_OFFSET; +} + void SetEntryRequired(GptEntry *e, int required) { e->attrs.fields.required = required; @@ -438,6 +444,14 @@ void SetEntryTries(GptEntry *e, int tries) CGPT_ATTRIBUTE_TRIES_MASK; } +void SetEntryErrorCounter(GptEntry *e, int error_counter) +{ + e->attrs.fields.gpt_att &= ~CGPT_ATTRIBUTE_ERROR_COUNTER_MASK; + e->attrs.fields.gpt_att |= + (error_counter << CGPT_ATTRIBUTE_ERROR_COUNTER_OFFSET) & + CGPT_ATTRIBUTE_ERROR_COUNTER_MASK; +} + void GetCurrentKernelUniqueGuid(GptData *gpt, void *dest) { GptEntry *entries = (GptEntry *)gpt->primary_entries; diff --git a/firmware/lib/cgptlib/include/cgptlib_internal.h b/firmware/lib/cgptlib/include/cgptlib_internal.h index 262e1fff..29f84f0f 100644 --- a/firmware/lib/cgptlib/include/cgptlib_internal.h +++ b/firmware/lib/cgptlib/include/cgptlib_internal.h @@ -22,7 +22,8 @@ * * 63-61 -- (reserved) * 60 -- read-only - * 59-57 -- (reserved) + * 59-58 -- (reserved) + * 57 -- error counter * 56 -- success * 55-52 -- tries * 51-48 -- priority @@ -31,6 +32,11 @@ * 1 -- UEFI: partition is not mapped * 0 -- UEFI: partition is required */ +#define CGPT_ATTRIBUTE_ERROR_COUNTER_OFFSET (57 - 48) +#define CGPT_ATTRIBUTE_MAX_ERROR_COUNTER (1ULL) +#define CGPT_ATTRIBUTE_ERROR_COUNTER_MASK (CGPT_ATTRIBUTE_MAX_ERROR_COUNTER << \ + CGPT_ATTRIBUTE_ERROR_COUNTER_OFFSET) + #define CGPT_ATTRIBUTE_SUCCESSFUL_OFFSET (56 - 48) #define CGPT_ATTRIBUTE_MAX_SUCCESSFUL (1ULL) #define CGPT_ATTRIBUTE_SUCCESSFUL_MASK (CGPT_ATTRIBUTE_MAX_SUCCESSFUL << \ diff --git a/host/include/cgpt_params.h b/host/include/cgpt_params.h index 64e31466..53c58475 100644 --- a/host/include/cgpt_params.h +++ b/host/include/cgpt_params.h @@ -35,6 +35,7 @@ typedef struct CgptAddParams { Guid type_guid; Guid unique_guid; const char *label; + int error_counter; int successful; int tries; int priority; @@ -45,6 +46,7 @@ typedef struct CgptAddParams { int set_size; int set_type; int set_unique; + int set_error_counter; int set_successful; int set_tries; int set_priority; diff --git a/tests/cgptlib_test.c b/tests/cgptlib_test.c index 2a71c399..3871da12 100644 --- a/tests/cgptlib_test.c +++ b/tests/cgptlib_test.c @@ -1174,19 +1174,30 @@ static int EntryAttributeGetSetTest(void) EXPECT(0xFFF0FFFFFFFFFFFFULL == e->attrs.whole); EXPECT(0 == GetEntryPriority(e)); + e->attrs.whole = 0x0000000000000000ULL; + SetEntryErrorCounter(e, 1); + EXPECT(0x0200000000000000ULL == e->attrs.whole); + EXPECT(1 == GetEntryErrorCounter(e)); + e->attrs.whole = 0xFFFFFFFFFFFFFFFFULL; + SetEntryErrorCounter(e, 0); + EXPECT(0xFDFFFFFFFFFFFFFFULL == e->attrs.whole); + EXPECT(0 == GetEntryErrorCounter(e)); + e->attrs.whole = 0xFFFFFFFFFFFFFFFFULL; EXPECT(1 == GetEntryRequired(e)); EXPECT(1 == GetEntryLegacyBoot(e)); EXPECT(1 == GetEntrySuccessful(e)); EXPECT(15 == GetEntryPriority(e)); EXPECT(15 == GetEntryTries(e)); + EXPECT(1 == GetEntryErrorCounter(e)); - e->attrs.whole = 0x0123000000000004ULL; + e->attrs.whole = 0x0323000000000004ULL; EXPECT(0 == GetEntryRequired(e)); EXPECT(1 == GetEntryLegacyBoot(e)); EXPECT(1 == GetEntrySuccessful(e)); EXPECT(2 == GetEntryTries(e)); EXPECT(3 == GetEntryPriority(e)); + EXPECT(1 == GetEntryErrorCounter(e)); return TEST_OK; } |