summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2014-10-31 15:18:48 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-11-05 06:05:01 +0000
commit6b5b8f65d52bc91ca37e5cb484867251d81136b1 (patch)
treea5611c53ec710ed4ea89d825d625b3dec12ff5c0
parentf97d3879d021159a8d5e050f4533da81f92b267d (diff)
downloadvboot-6b5b8f65d52bc91ca37e5cb484867251d81136b1.tar.gz
vboot2: use common header size fields
Add functions for verifying object integrity using common header size fields. Convert vb2_packed_key2 to use the the new functions. This isn't much prettier for packed keys; the benefit is more obvious for keyblocks (coming next). BUG=chromium:423882 BRANCH=none TEST=VBOOT2=1 make runtests Change-Id: I0c09533368abb7ced3b5ac622a15e62832413b7f Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/226874 Reviewed-by: Bill Richardson <wfrichar@chromium.org>
-rw-r--r--Makefile1
-rw-r--r--firmware/2lib/2common.c24
-rw-r--r--firmware/2lib/2common2.c120
-rw-r--r--firmware/2lib/2packed_key2.c29
-rw-r--r--firmware/2lib/include/2common.h49
-rw-r--r--firmware/2lib/include/2return_codes.h60
-rw-r--r--tests/vb2_common2_tests.c8
-rw-r--r--tests/vb2_common_tests.c171
8 files changed, 365 insertions, 97 deletions
diff --git a/Makefile b/Makefile
index c72c6a7e..146c042d 100644
--- a/Makefile
+++ b/Makefile
@@ -283,6 +283,7 @@ VBSLK_SRCS = \
FWLIB2_SRCS = \
firmware/2lib/2api.c \
firmware/2lib/2common.c \
+ firmware/2lib/2common2.c \
firmware/2lib/2crc8.c \
firmware/2lib/2misc.c \
firmware/2lib/2nvstorage.c \
diff --git a/firmware/2lib/2common.c b/firmware/2lib/2common.c
index 221e6115..9a729e22 100644
--- a/firmware/2lib/2common.c
+++ b/firmware/2lib/2common.c
@@ -159,30 +159,6 @@ int vb2_verify_member_inside(const void *parent, size_t parent_size,
return VB2_SUCCESS;
}
-int vb2_verify_common_header(const void *parent,
- uint32_t parent_size,
- const struct vb2_struct_common *c)
-{
- int rv;
-
- /* Make sure common data and description are inside parent */
- rv = vb2_verify_member_inside(parent, parent_size,
- c, sizeof(*c),
- c->fixed_size, c->desc_size);
- if (rv)
- return rv;
-
- /* Check description */
- if (c->desc_size > 0) {
- /* Description must be null-terminated */
- const uint8_t *desc = (const uint8_t *)c + c->fixed_size;
- if (desc[c->desc_size - 1] != 0)
- return VB2_ERROR_DESC_TERMINATOR;
- }
-
- return VB2_SUCCESS;
-}
-
int vb2_verify_signature_inside(const void *parent,
uint32_t parent_size,
const struct vb2_signature *sig)
diff --git a/firmware/2lib/2common2.c b/firmware/2lib/2common2.c
new file mode 100644
index 00000000..b65ea8fd
--- /dev/null
+++ b/firmware/2lib/2common2.c
@@ -0,0 +1,120 @@
+/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Signature validation functions
+ */
+
+#include "2sysincludes.h"
+#include "2common.h"
+#include "2rsa.h"
+#include "2sha.h"
+
+int vb2_verify_common_header(const void *parent, uint32_t parent_size)
+{
+ const struct vb2_struct_common *c = parent;
+
+ /* Parent buffer size must be at least the claimed total size */
+ if (parent_size < c->total_size)
+ return VB2_ERROR_COMMON_TOTAL_SIZE;
+
+ /*
+ * And big enough for the fixed size, which itself must be at least as
+ * big as the common struct header.
+ */
+ if (c->total_size < c->fixed_size || c->fixed_size < sizeof(*c))
+ return VB2_ERROR_COMMON_FIXED_SIZE;
+
+ /* Make sure sizes are all multiples of 32 bits */
+ if (!vb2_aligned(c->total_size, sizeof(uint32_t)))
+ return VB2_ERROR_COMMON_TOTAL_UNALIGNED;
+ if (!vb2_aligned(c->fixed_size, sizeof(uint32_t)))
+ return VB2_ERROR_COMMON_FIXED_UNALIGNED;
+ if (!vb2_aligned(c->desc_size, sizeof(uint32_t)))
+ return VB2_ERROR_COMMON_DESC_UNALIGNED;
+
+ /* Check description */
+ if (c->desc_size > 0) {
+ /* Make sure description fits and doesn't wrap */
+ if (c->fixed_size + c->desc_size < c->fixed_size)
+ return VB2_ERROR_COMMON_DESC_WRAPS;
+ if (c->fixed_size + c->desc_size > c->total_size)
+ return VB2_ERROR_COMMON_DESC_SIZE;
+
+ /* Description must be null-terminated */
+ const uint8_t *desc = (const uint8_t *)c + c->fixed_size;
+ if (desc[c->desc_size - 1] != 0)
+ return VB2_ERROR_COMMON_DESC_TERMINATOR;
+ }
+
+ return VB2_SUCCESS;
+}
+
+int vb2_verify_common_member(const void *parent,
+ uint32_t *min_offset,
+ uint32_t member_offset,
+ uint32_t member_size)
+{
+ const struct vb2_struct_common *c = parent;
+ uint32_t member_end = member_offset + member_size;
+
+ /* Make sure member doesn't wrap */
+ if (member_end < member_offset)
+ return VB2_ERROR_COMMON_MEMBER_WRAPS;
+
+ /* Member offset and size must be 32-bit aligned */
+ if (!vb2_aligned(member_offset, sizeof(uint32_t)) ||
+ !vb2_aligned(member_size, sizeof(uint32_t)))
+ return VB2_ERROR_COMMON_MEMBER_UNALIGNED;
+
+ /* Initialize minimum offset if necessary */
+ if (!*min_offset)
+ *min_offset = c->fixed_size + c->desc_size;
+
+ /* Member must be after minimum offset */
+ if (member_offset < *min_offset)
+ return VB2_ERROR_COMMON_MEMBER_OVERLAP;
+
+ /* Member must end before total size */
+ if (member_end > c->total_size)
+ return VB2_ERROR_COMMON_MEMBER_SIZE;
+
+ /* Update minimum offset for subsequent checks */
+ *min_offset = member_end;
+
+ return VB2_SUCCESS;
+}
+
+int vb2_verify_common_subobject(const void *parent,
+ uint32_t *min_offset,
+ uint32_t member_offset)
+{
+ const struct vb2_struct_common *p = parent;
+ const struct vb2_struct_common *m =
+ (const struct vb2_struct_common *)
+ ((const uint8_t *)parent + member_offset);
+ int rv;
+
+ /*
+ * Verify the parent has space at the member offset for the common
+ * header.
+ */
+ rv = vb2_verify_common_member(parent, min_offset, member_offset,
+ sizeof(*m));
+ if (rv)
+ return rv;
+
+ /*
+ * Now it's safe to look at the member's header, and verify any
+ * additional data for the object past its common header fits in the
+ * parent.
+ */
+ rv = vb2_verify_common_header(m, p->total_size - member_offset);
+ if (rv)
+ return rv;
+
+ /* Advance the min offset to the end of the subobject */
+ *min_offset = member_offset + m->total_size;
+
+ return VB2_SUCCESS;
+}
diff --git a/firmware/2lib/2packed_key2.c b/firmware/2lib/2packed_key2.c
index 22fa0a40..e8289273 100644
--- a/firmware/2lib/2packed_key2.c
+++ b/firmware/2lib/2packed_key2.c
@@ -14,21 +14,6 @@ const uint8_t *vb2_packed_key2_data(const struct vb2_packed_key2 *key)
return (const uint8_t *)key + key->key_offset;
}
-int vb2_verify_packed_key2_inside(const void *parent,
- uint32_t parent_size,
- const struct vb2_packed_key2 *key)
-{
- int rv;
-
- rv = vb2_verify_member_inside(parent, parent_size,
- key, sizeof(*key),
- key->key_offset, key->key_size);
- if (rv)
- return rv;
-
- return vb2_verify_common_header(parent, parent_size, &key->c);
-}
-
int vb2_unpack_key2(struct vb2_public_key *key,
const uint8_t *buf,
uint32_t size)
@@ -38,6 +23,7 @@ int vb2_unpack_key2(struct vb2_public_key *key,
const uint32_t *buf32;
uint32_t expected_key_size;
uint32_t sig_size;
+ uint32_t min_offset = 0;
int rv;
/*
@@ -51,8 +37,13 @@ int vb2_unpack_key2(struct vb2_public_key *key,
if (pkey->c.magic != VB2_MAGIC_PACKED_KEY2)
return vb2_unpack_key(key, buf, size);
- /* Make sure passed buffer is big enough for the packed key */
- rv = vb2_verify_packed_key2_inside(buf, size, pkey);
+ rv = vb2_verify_common_header(buf, size);
+ if (rv)
+ return rv;
+
+ /* Make sure key data is inside */
+ rv = vb2_verify_common_member(pkey, &min_offset,
+ pkey->key_offset, pkey->key_size);
if (rv)
return rv;
@@ -80,10 +71,8 @@ int vb2_unpack_key2(struct vb2_public_key *key,
return VB2_ERROR_UNPACK_KEY_SIZE;
}
- /* Make sure source buffer is 32-bit aligned */
+ /* Unpack key data */
buf32 = (const uint32_t *)vb2_packed_key2_data(pkey);
- if (!vb2_aligned(buf32, sizeof(uint32_t)))
- return VB2_ERROR_UNPACK_KEY_ALIGN;
/* Sanity check key array size */
key->arrsize = buf32[0];
diff --git a/firmware/2lib/include/2common.h b/firmware/2lib/include/2common.h
index 5ab145cf..f92fe9e4 100644
--- a/firmware/2lib/include/2common.h
+++ b/firmware/2lib/include/2common.h
@@ -28,9 +28,7 @@ struct vb2_public_key;
#define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))
#endif
-/*
- * Debug output. printf() for tests. otherwise, it's platform-dependent.
- */
+/* Debug output printf() for tests. Otherwise, it's platform-dependent. */
#if defined(VBOOT_DEBUG)
# if defined(FOR_TEST)
# define VB2_DEBUG(format, args...) printf(format, ## args)
@@ -187,12 +185,47 @@ int vb2_verify_member_inside(const void *parent, size_t parent_size,
*
* @param parent Parent data
* @param parent_size Parent size in bytes
- * @param sig Signature pointer
* @return VB2_SUCCESS, or non-zero if error.
*/
-int vb2_verify_common_header(const void *parent,
- uint32_t parent_size,
- const struct vb2_struct_common *c);
+int vb2_verify_common_header(const void *parent, uint32_t parent_size);
+
+/**
+ * Verify a member is within the data for a parent object
+ *
+ * @param parent Parent data (starts with struct vb2_struct_common)
+ * @param min_offset Pointer to minimum offset where member can be located.
+ * If this offset is 0 on input, uses the size of the
+ * fixed header (and description, if any). This will be
+ * updated on return to the end of the passed member.
+ * @param member_offset Offset of member data from start of parent, in bytes
+ * @param member_size Size of member data, in bytes
+ * @return VB2_SUCCESS, or non-zero if error.
+ */
+int vb2_verify_common_member(const void *parent,
+ uint32_t *min_offset,
+ uint32_t member_offset,
+ uint32_t member_size);
+
+/**
+ * Verify a member which starts with a common header is within the parent
+ *
+ * This does not verify the contents of the member or its header, only that the
+ * member's claimed total size fits within the parent's claimed total size at
+ * the specified offset.
+ *
+ * @param parent Parent data (starts with struct vb2_struct_common)
+ * @param min_offset Pointer to minimum offset where member can be located.
+ * If this offset is 0 on input, uses the size of the
+ * fixed header (and description, if any). This will be
+ * updated on return to the end of the passed member.
+ * @param member_offset Offset of member data from start of parent, in bytes.
+ * This should be the start of the common header of the
+ * member.
+ * @return VB2_SUCCESS, or non-zero if error.
+ */
+int vb2_verify_common_subobject(const void *parent,
+ uint32_t *min_offset,
+ uint32_t member_offset);
/**
* Verify a signature is fully contained in its parent data
@@ -219,7 +252,7 @@ int vb2_verify_packed_key_inside(const void *parent,
const struct vb2_packed_key *key);
/**
- * Unpack a RSA key for use in verification
+ * Unpack a vboot1-format key for use in verification
*
* The elements of the unpacked key will point into the source buffer, so don't
* free the source buffer until you're done with the key.
diff --git a/firmware/2lib/include/2return_codes.h b/firmware/2lib/include/2return_codes.h
index aca6b715..a65c334f 100644
--- a/firmware/2lib/include/2return_codes.h
+++ b/firmware/2lib/include/2return_codes.h
@@ -132,7 +132,7 @@ enum vb2_return_code {
VB2_ERROR_INSIDE_DATA_OUTSIDE,
/* Unsupported signature algorithm in vb2_unpack_key() */
- VB2_ERROR_UNPACK_KEY_SIG_ALGORITHM,
+ VB2_ERROR_UNPACK_KEY_SIG_ALGORITHM, /* 0x150008 */
/* Bad key size in vb2_unpack_key() */
VB2_ERROR_UNPACK_KEY_SIZE,
@@ -156,7 +156,7 @@ enum vb2_return_code {
VB2_ERROR_VDATA_WORKBUF_DIGEST,
/* Not enough work buffer for hash temp data in vb2_verify_data() */
- VB2_ERROR_VDATA_WORKBUF_HASHING,
+ VB2_ERROR_VDATA_WORKBUF_HASHING, /* 0x150010 */
/*
* Bad digest size in vb2_verify_data() - probably because algorithm
@@ -167,15 +167,59 @@ enum vb2_return_code {
/* Unsupported hash algorithm in vb2_unpack_key() */
VB2_ERROR_UNPACK_KEY_HASH_ALGORITHM,
- /* Common struct description is not null-terminated */
- VB2_ERROR_DESC_TERMINATOR,
-
/* Member data overlaps member header */
VB2_ERROR_INSIDE_DATA_OVERLAP,
/* Unsupported packed key struct version */
VB2_ERROR_UNPACK_KEY_STRUCT_VERSION,
+ /*
+ * Buffer too small for total, fixed size, or description reported in
+ * common header, or member data checked via
+ * vb2_verify_common_member().
+ */
+ VB2_ERROR_COMMON_TOTAL_SIZE,
+ VB2_ERROR_COMMON_FIXED_SIZE,
+ VB2_ERROR_COMMON_DESC_SIZE,
+ VB2_ERROR_COMMON_MEMBER_SIZE, /* 0x150018 */
+
+ /*
+ * Total, fixed, description, or member offset/size not a multiple of
+ * 32 bits.
+ */
+ VB2_ERROR_COMMON_TOTAL_UNALIGNED,
+ VB2_ERROR_COMMON_FIXED_UNALIGNED,
+ VB2_ERROR_COMMON_DESC_UNALIGNED,
+ VB2_ERROR_COMMON_MEMBER_UNALIGNED,
+
+ /* Common struct description or member data wraps address space */
+ VB2_ERROR_COMMON_DESC_WRAPS,
+ VB2_ERROR_COMMON_MEMBER_WRAPS,
+
+ /* Common struct description is not null-terminated */
+ VB2_ERROR_COMMON_DESC_TERMINATOR,
+
+ /* Member data overlaps previous data */
+ VB2_ERROR_COMMON_MEMBER_OVERLAP, /* 0x150020 */
+
+ /* Signature bad magic number */
+ VB2_ERROR_SIG_MAGIC,
+
+ /* Signature incompatible version */
+ VB2_ERROR_SIG_VERSION,
+
+ /* Signature header doesn't fit */
+ VB2_ERROR_SIG_HEADER_SIZE,
+
+ /* Wrong amount of data signed */
+ VB2_ERROR_VDATA_SIZE,
+
+ /* Digest mismatch */
+ VB2_ERROR_VDATA_VERIFY_DIGEST,
+
+ /* Key algorithm doesn't match signature algorithm */
+ VB2_ERROR_VDATA_ALGORITHM_MISMATCH,
+
/**********************************************************************
* Keyblock verification errors (all in vb2_verify_keyblock())
*/
@@ -211,6 +255,12 @@ enum vb2_return_code {
/* Data key outside signed part of keyblock */
VB2_ERROR_KEYBLOCK_DATA_KEY_UNSIGNED,
+ /* Signature signed wrong amount of data */
+ VB2_ERROR_KEYBLOCK_SIGNED_SIZE,
+
+ /* No signature matching key GUID */
+ VB2_ERROR_KEYBLOCK_SIG_GUID,
+
/**********************************************************************
* Preamble verification errors (all in vb2_verify_preamble())
*/
diff --git a/tests/vb2_common2_tests.c b/tests/vb2_common2_tests.c
index c2d11d99..050695ee 100644
--- a/tests/vb2_common2_tests.c
+++ b/tests/vb2_common2_tests.c
@@ -99,14 +99,14 @@ static void test_unpack_key2(const VbPublicKey *orig_key)
key2 = vb2_convert_packed_key2(key1, "Test key", &size);
key2->key_offset += 4;
TEST_EQ(vb2_unpack_key2(&pubk, (uint8_t *)key2, size),
- VB2_ERROR_INSIDE_DATA_OUTSIDE,
+ VB2_ERROR_COMMON_MEMBER_SIZE,
"vb2_unpack_key2() buffer too small");
free(key2);
key2 = vb2_convert_packed_key2(key1, "Test key", &size);
key2->c.fixed_size += size;
TEST_EQ(vb2_unpack_key2(&pubk, (uint8_t *)key2, size),
- VB2_ERROR_INSIDE_DATA_OUTSIDE,
+ VB2_ERROR_COMMON_FIXED_SIZE,
"vb2_unpack_key2() buffer too small for desc");
free(key2);
@@ -161,7 +161,7 @@ static void test_unpack_key2(const VbPublicKey *orig_key)
free(key2);
key2 = vb2_convert_packed_key2(key1, "Test key", &size);
- key2->key_size--;
+ key2->key_size -= 4;
TEST_EQ(vb2_unpack_key2(&pubk, (uint8_t *)key2, size),
VB2_ERROR_UNPACK_KEY_SIZE,
"vb2_unpack_key2() invalid size");
@@ -170,7 +170,7 @@ static void test_unpack_key2(const VbPublicKey *orig_key)
key2 = vb2_convert_packed_key2(key1, "Test key", &size);
key2->key_offset--;
TEST_EQ(vb2_unpack_key2(&pubk, (uint8_t *)key2, size),
- VB2_ERROR_UNPACK_KEY_ALIGN,
+ VB2_ERROR_COMMON_MEMBER_UNALIGNED,
"vb2_unpack_key2() unaligned data");
free(key2);
diff --git a/tests/vb2_common_tests.c b/tests/vb2_common_tests.c
index 31fa036d..8f93a44c 100644
--- a/tests/vb2_common_tests.c
+++ b/tests/vb2_common_tests.c
@@ -243,42 +243,6 @@ static void test_helper_functions(void)
}
{
- uint8_t cbuf[sizeof(struct vb2_struct_common) + 128];
- struct vb2_struct_common *c = (struct vb2_struct_common *)cbuf;
-
- c->total_size = sizeof(cbuf);
- c->fixed_size = sizeof(*c);
- c->desc_size = 128;
- cbuf[sizeof(cbuf) - 1] = 0;
- TEST_SUCC(vb2_verify_common_header(cbuf, sizeof(cbuf), c),
- "CommonInside at start");
-
- c[1].fixed_size = sizeof(*c);
- c[1].desc_size = 128 - sizeof(*c);
- TEST_SUCC(vb2_verify_common_header(cbuf, sizeof(cbuf), c + 1),
- "CommonInside after start");
-
- TEST_EQ(vb2_verify_common_header(cbuf, sizeof(cbuf) - 1, c),
- VB2_ERROR_INSIDE_DATA_OUTSIDE,
- "CommonInside key too big");
-
- c->fixed_size = sizeof(cbuf);
- TEST_EQ(vb2_verify_common_header(cbuf, sizeof(cbuf), c),
- VB2_ERROR_INSIDE_DATA_OUTSIDE,
- "CommonInside offset too big");
- c->fixed_size = sizeof(*c);
-
- cbuf[sizeof(cbuf) - 1] = 1;
- TEST_EQ(vb2_verify_common_header(cbuf, sizeof(cbuf), c),
- VB2_ERROR_DESC_TERMINATOR,
- "CommonInside description not terminated");
-
- c->desc_size = 0;
- TEST_SUCC(vb2_verify_common_header(cbuf, sizeof(cbuf), c),
- "CommonInside no description");
- }
-
- {
struct vb2_packed_key k = {.key_offset = sizeof(k),
.key_size = 128};
TEST_SUCC(vb2_verify_packed_key_inside(&k, sizeof(k)+128, &k),
@@ -321,6 +285,140 @@ static void test_helper_functions(void)
}
}
+/**
+ * Common header functions
+ */
+static void test_common_header_functions(void)
+{
+ uint8_t cbuf[sizeof(struct vb2_struct_common) + 128];
+ uint8_t cbufgood[sizeof(cbuf)];
+ struct vb2_struct_common *c = (struct vb2_struct_common *)cbuf;
+ struct vb2_struct_common *c2;
+ uint32_t desc_end, m;
+
+ c->total_size = sizeof(cbuf);
+ c->fixed_size = sizeof(*c);
+ c->desc_size = 32;
+ desc_end = c->fixed_size + c->desc_size;
+ cbuf[desc_end - 1] = 0;
+
+ c2 = (struct vb2_struct_common *)(cbuf + desc_end);
+ c2->total_size = c->total_size - desc_end;
+ c2->fixed_size = sizeof(*c2);
+ c2->desc_size = 0;
+
+ TEST_SUCC(vb2_verify_common_header(cbuf, sizeof(cbuf)),
+ "vb2_verify_common_header() good");
+ memcpy(cbufgood, cbuf, sizeof(cbufgood));
+
+ memcpy(cbuf, cbufgood, sizeof(cbuf));
+ c->total_size += 4;
+ TEST_EQ(vb2_verify_common_header(cbuf, sizeof(cbuf)),
+ VB2_ERROR_COMMON_TOTAL_SIZE,
+ "vb2_verify_common_header() total size");
+
+ memcpy(cbuf, cbufgood, sizeof(cbuf));
+ c->fixed_size = c->total_size + 4;
+ TEST_EQ(vb2_verify_common_header(cbuf, sizeof(cbuf)),
+ VB2_ERROR_COMMON_FIXED_SIZE,
+ "vb2_verify_common_header() fixed size");
+
+ memcpy(cbuf, cbufgood, sizeof(cbuf));
+ c->desc_size = c->total_size - c->fixed_size + 4;
+ TEST_EQ(vb2_verify_common_header(cbuf, sizeof(cbuf)),
+ VB2_ERROR_COMMON_DESC_SIZE,
+ "vb2_verify_common_header() desc size");
+
+ memcpy(cbuf, cbufgood, sizeof(cbuf));
+ c->total_size--;
+ TEST_EQ(vb2_verify_common_header(cbuf, sizeof(cbuf)),
+ VB2_ERROR_COMMON_TOTAL_UNALIGNED,
+ "vb2_verify_common_header() total unaligned");
+
+ memcpy(cbuf, cbufgood, sizeof(cbuf));
+ c->fixed_size++;
+ TEST_EQ(vb2_verify_common_header(cbuf, sizeof(cbuf)),
+ VB2_ERROR_COMMON_FIXED_UNALIGNED,
+ "vb2_verify_common_header() fixed unaligned");
+
+ memcpy(cbuf, cbufgood, sizeof(cbuf));
+ c->desc_size--;
+ TEST_EQ(vb2_verify_common_header(cbuf, sizeof(cbuf)),
+ VB2_ERROR_COMMON_DESC_UNALIGNED,
+ "vb2_verify_common_header() desc unaligned");
+
+ memcpy(cbuf, cbufgood, sizeof(cbuf));
+ c->desc_size = -4;
+ TEST_EQ(vb2_verify_common_header(cbuf, sizeof(cbuf)),
+ VB2_ERROR_COMMON_DESC_WRAPS,
+ "vb2_verify_common_header() desc wraps");
+
+ memcpy(cbuf, cbufgood, sizeof(cbuf));
+ cbuf[desc_end - 1] = 1;
+ TEST_EQ(vb2_verify_common_header(cbuf, sizeof(cbuf)),
+ VB2_ERROR_COMMON_DESC_TERMINATOR,
+ "vb2_verify_common_header() desc not terminated");
+
+ /* Member checking function */
+ memcpy(cbuf, cbufgood, sizeof(cbuf));
+ m = 0;
+ TEST_SUCC(vb2_verify_common_member(cbuf, &m, c->total_size - 8, 4),
+ "vb2_verify_common_member()");
+ TEST_EQ(m, c->total_size - 4, " new minimum");
+
+ m = desc_end;
+ TEST_SUCC(vb2_verify_common_member(cbuf, &m, desc_end, 4),
+ "vb2_verify_common_member() good offset");
+ TEST_EQ(m, desc_end + 4, " new minimum");
+
+ m = 0;
+ TEST_EQ(vb2_verify_common_member(cbuf, &m, c->total_size - 8, -4),
+ VB2_ERROR_COMMON_MEMBER_WRAPS,
+ "vb2_verify_common_member() wraps");
+
+ m = 0;
+ TEST_EQ(vb2_verify_common_member(cbuf, &m, c->total_size - 7, 4),
+ VB2_ERROR_COMMON_MEMBER_UNALIGNED,
+ "vb2_verify_common_member() offset unaligned");
+
+ m = 0;
+ TEST_EQ(vb2_verify_common_member(cbuf, &m, c->total_size - 8, 5),
+ VB2_ERROR_COMMON_MEMBER_UNALIGNED,
+ "vb2_verify_common_member() size unaligned");
+
+ m = 0;
+ TEST_EQ(vb2_verify_common_member(cbuf, &m, desc_end - 4, 4),
+ VB2_ERROR_COMMON_MEMBER_OVERLAP,
+ "vb2_verify_common_member() overlap");
+
+ m = desc_end + 4;
+ TEST_EQ(vb2_verify_common_member(cbuf, &m, desc_end, 4),
+ VB2_ERROR_COMMON_MEMBER_OVERLAP,
+ "vb2_verify_common_member() overlap 2");
+
+ m = 0;
+ TEST_EQ(vb2_verify_common_member(cbuf, &m, c->total_size - 4, 8),
+ VB2_ERROR_COMMON_MEMBER_SIZE,
+ "vb2_verify_common_member() size");
+
+ /* Subobject checking */
+ m = 0;
+ TEST_SUCC(vb2_verify_common_subobject(cbuf, &m, desc_end),
+ "vb2_verify_common_subobject() good offset");
+ TEST_EQ(m, sizeof(cbuf), " new minimum");
+
+ m = desc_end + 4;
+ TEST_EQ(vb2_verify_common_subobject(cbuf, &m, desc_end),
+ VB2_ERROR_COMMON_MEMBER_OVERLAP,
+ "vb2_verify_common_subobject() overlap");
+
+ m = 0;
+ c2->total_size += 4;
+ TEST_EQ(vb2_verify_common_subobject(cbuf, &m, desc_end),
+ VB2_ERROR_COMMON_TOTAL_SIZE,
+ "vb2_verify_common_subobject() size");
+}
+
int main(int argc, char* argv[])
{
test_memcmp();
@@ -328,6 +426,7 @@ int main(int argc, char* argv[])
test_workbuf();
test_struct_packing();
test_helper_functions();
+ test_common_header_functions();
return gTestSuccess ? 0 : 255;
}