summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJae Hoon Kim <kimjae@chromium.org>2023-03-24 22:24:06 +0000
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-03-28 07:04:05 +0000
commit6d1c48e3179056d965edfdd630a9dd6cda12f14b (patch)
tree63cb681341649c7f88ebb14ef846db8e7e126435
parent64e9aec36289ade7e7372e41a4e599d86948a97a (diff)
downloadvboot-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.h3
-rw-r--r--cgpt/cgpt_add.c5
-rw-r--r--cgpt/cgpt_common.c15
-rw-r--r--cgpt/cgpt_show.c7
-rw-r--r--cgpt/cmd_add.c9
-rw-r--r--firmware/include/gpt_misc.h2
-rw-r--r--firmware/lib/cgptlib/cgptlib_internal.c14
-rw-r--r--firmware/lib/cgptlib/include/cgptlib_internal.h8
-rw-r--r--host/include/cgpt_params.h2
-rw-r--r--tests/cgptlib_test.c13
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(&params->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(&params->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;
}