libpayload/libcbfs: Fix file hash check
Fix the buffer pointer passed to cbfs_file_hash_mismatch().
Add a test case with LZ4 compression, which would catch the bug we are
fixing.
Change-Id: I36605e2dbc0423fa6743087512f2042b37c49d35
Signed-off-by: Yu-Ping Wu <yupingso@chromium.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/65149
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Paul Menzel <paulepanter@mailbox.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
diff --git a/payloads/libpayload/libcbfs/cbfs.c b/payloads/libpayload/libcbfs/cbfs.c
index ff19179..0694c4f 100644
--- a/payloads/libpayload/libcbfs/cbfs.c
+++ b/payloads/libpayload/libcbfs/cbfs.c
@@ -120,7 +120,7 @@
goto out;
}
- if (cbfs_file_hash_mismatch(buffer, in_size, mdata, skip_verification))
+ if (cbfs_file_hash_mismatch(load, in_size, mdata, skip_verification))
goto out;
switch (compression) {
diff --git a/payloads/libpayload/tests/libcbfs/cbfs-verification-test.c b/payloads/libpayload/tests/libcbfs/cbfs-verification-test.c
index 1dcccf9..8e50f39 100644
--- a/payloads/libpayload/tests/libcbfs/cbfs-verification-test.c
+++ b/payloads/libpayload/tests/libcbfs/cbfs-verification-test.c
@@ -43,14 +43,18 @@
unsigned long ulzman(const unsigned char *src, unsigned long srcn, unsigned char *dst,
unsigned long dstn)
{
- fail_msg("Unexpected call to %s", __func__);
- return 0;
+ size_t copy_size = MIN(srcn, dstn);
+ function_called();
+ memcpy(dst, src, copy_size);
+ return copy_size;
}
size_t ulz4fn(const void *src, size_t srcn, void *dst, size_t dstn)
{
- fail_msg("Unexpected call to %s", __func__);
- return 0;
+ size_t copy_size = MIN(srcn, dstn);
+ function_called();
+ memcpy(dst, src, copy_size);
+ return copy_size;
}
enum cb_err cbfs_mcache_lookup(const void *mcache, size_t mcache_size, const char *name,
@@ -167,7 +171,7 @@
}
}
-static void test_cbfs_map_valid_hash(void **state)
+static void test_cbfs_map_valid_hash_impl(void **state, bool lz4_compressed)
{
void *mapping = NULL;
size_t size = 0;
@@ -181,8 +185,17 @@
expect_cbfs_lookup(TEST_DATA_1_FILENAME, CB_SUCCESS,
(const union cbfs_mdata *)&file_valid_hash,
be32toh(file_valid_hash.header.offset));
- will_return(cbfs_find_attr, NULL);
+ if (lz4_compressed) {
+ struct cbfs_file_attr_compression cattr = {
+ .compression = htobe32(CBFS_COMPRESS_LZ4),
+ .decompressed_size = htobe32(TEST_DATA_1_SIZE),
+ };
+ will_return(cbfs_find_attr, &cattr);
+ expect_function_call(ulz4fn);
+ } else {
+ will_return(cbfs_find_attr, NULL);
+ }
if (CONFIG(LP_CBFS_VERIFICATION)) {
will_return(cbfs_file_hash, &hash);
@@ -203,6 +216,16 @@
}
}
+static void test_cbfs_map_valid_hash(void **state)
+{
+ test_cbfs_map_valid_hash_impl(state, false);
+}
+
+static void test_cbfs_map_valid_hash_with_lz4(void **state)
+{
+ test_cbfs_map_valid_hash_impl(state, true);
+}
+
static void test_cbfs_map_invalid_hash(void **state)
{
void *mapping = NULL;
@@ -240,6 +263,7 @@
const struct CMUnitTest tests[] = {
cmocka_unit_test_setup(test_cbfs_map_no_hash, setup_test_cbfs),
cmocka_unit_test_setup(test_cbfs_map_valid_hash, setup_test_cbfs),
+ cmocka_unit_test_setup(test_cbfs_map_valid_hash_with_lz4, setup_test_cbfs),
cmocka_unit_test_setup(test_cbfs_map_invalid_hash, setup_test_cbfs),
};