mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
test: Add BCD unit test
This commit is contained in:
parent
986fd3ebc2
commit
db7f5ab68f
13
meson.build
13
meson.build
@ -1676,8 +1676,14 @@ conf.set10('ENABLE_TIMEDATECTL', get_option('timedated') or get_option('timesync
|
||||
|
||||
conf.set10('SYSTEMD_SLOW_TESTS_DEFAULT', slow_tests)
|
||||
|
||||
#####################################################################
|
||||
############################################################
|
||||
|
||||
tests = []
|
||||
fuzzers = []
|
||||
|
||||
############################################################
|
||||
|
||||
# Include these now as they provide gnu-efi detection.
|
||||
subdir('src/fundamental')
|
||||
subdir('src/boot/efi')
|
||||
|
||||
@ -1695,7 +1701,7 @@ update_syscall_tables_sh = find_program('tools/update-syscall-tables.sh')
|
||||
xml_helper_py = find_program('tools/xml_helper.py')
|
||||
export_dbus_interfaces_py = find_program('tools/dbus_exporter.py')
|
||||
|
||||
#####################################################################
|
||||
############################################################
|
||||
|
||||
config_h = configure_file(
|
||||
output : 'config.h',
|
||||
@ -1716,9 +1722,6 @@ if dbus_interfaces_dir == ''
|
||||
dbus_interfaces_dir = get_option('datadir') + '/dbus-1'
|
||||
endif
|
||||
|
||||
tests = []
|
||||
fuzzers = []
|
||||
|
||||
basic_includes = include_directories(
|
||||
'src/basic',
|
||||
'src/fundamental',
|
||||
|
@ -1,8 +1,27 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <efi.h>
|
||||
#include "macro-fundamental.h"
|
||||
#include "util.h"
|
||||
#ifdef SD_BOOT
|
||||
# include <efi.h>
|
||||
# include "macro-fundamental.h"
|
||||
# include "util.h"
|
||||
# define TEST_STATIC
|
||||
#else
|
||||
/* Provide our own "EFI API" if we are running as a unit test. */
|
||||
# include <stddef.h>
|
||||
# include <stdint.h>
|
||||
# include <uchar.h>
|
||||
# include "string-util-fundamental.h"
|
||||
|
||||
# define CHAR8 char
|
||||
# define CHAR16 char16_t
|
||||
# define UINT8 uint8_t
|
||||
# define UINT16 uint16_t
|
||||
# define UINT32 uint32_t
|
||||
# define UINT64 uint64_t
|
||||
# define UINTN size_t
|
||||
# define strncaseeqa(a, b, n) strncaseeq((a), (b), (n))
|
||||
# define TEST_STATIC static
|
||||
#endif
|
||||
|
||||
enum {
|
||||
SIG_BASE_BLOCK = 1718052210, /* regf */
|
||||
@ -206,7 +225,7 @@ static const KeyValue *get_key_value(const UINT8 *bcd, UINT32 bcd_len, const Key
|
||||
* (it always has the GUID 9dea862c-5cdd-4e70-acc1-f32b344d4795). If it contains more than
|
||||
* one GUID, the BCD is multi-boot and we stop looking. Otherwise we take that GUID, look it
|
||||
* up, and return its description property. */
|
||||
CHAR16 *get_bcd_title(UINT8 *bcd, UINTN bcd_len) {
|
||||
TEST_STATIC CHAR16 *get_bcd_title(UINT8 *bcd, UINTN bcd_len) {
|
||||
assert(bcd);
|
||||
|
||||
if (HIVE_CELL_OFFSET > bcd_len)
|
||||
|
@ -373,6 +373,14 @@ endforeach
|
||||
|
||||
############################################################
|
||||
|
||||
tests += [
|
||||
[['src/boot/efi/test-bcd.c'],
|
||||
[],
|
||||
[libzstd],
|
||||
[],
|
||||
'HAVE_ZSTD'],
|
||||
]
|
||||
|
||||
test_efi_disk_img = custom_target(
|
||||
'test-efi-disk.img',
|
||||
input : [efi_stubs[0][0], efi_stubs[1][1]],
|
||||
|
162
src/boot/efi/test-bcd.c
Normal file
162
src/boot/efi/test-bcd.c
Normal file
@ -0,0 +1,162 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "compress.h"
|
||||
#include "fileio.h"
|
||||
#include "tests.h"
|
||||
#include "utf8.h"
|
||||
|
||||
/* Inlcude the implementation directly, so we can poke at some internals. */
|
||||
#include "bcd.c"
|
||||
|
||||
static void load_bcd(const char *path, void **ret_bcd, size_t *ret_bcd_len) {
|
||||
size_t len;
|
||||
_cleanup_free_ char *fn = NULL, *compressed = NULL;
|
||||
|
||||
assert_se(get_testdata_dir(path, &fn) >= 0);
|
||||
assert_se(read_full_file_full(AT_FDCWD, fn, UINT64_MAX, SIZE_MAX, 0, NULL, &compressed, &len) >= 0);
|
||||
assert_se(decompress_blob_zstd(compressed, len, ret_bcd, ret_bcd_len, SIZE_MAX) >= 0);
|
||||
}
|
||||
|
||||
static void test_get_bcd_title_one(
|
||||
const char *path,
|
||||
const char16_t *title_expect,
|
||||
size_t title_len_expect) {
|
||||
|
||||
size_t len;
|
||||
_cleanup_free_ void *bcd = NULL;
|
||||
|
||||
log_info("/* %s(%s) */", __func__, path);
|
||||
|
||||
load_bcd(path, &bcd, &len);
|
||||
|
||||
char16_t *title = get_bcd_title(bcd, len);
|
||||
if (title_expect) {
|
||||
assert_se(title);
|
||||
assert_se(memcmp(title, title_expect, title_len_expect) == 0);
|
||||
} else
|
||||
assert_se(!title);
|
||||
}
|
||||
|
||||
TEST(get_bcd_title) {
|
||||
const char16_t win10[] = { 'W', 'i', 'n', 'd', 'o', 'w', 's', ' ', '1', '0', '\0' };
|
||||
test_get_bcd_title_one("test-bcd/win10.bcd.zst", win10, sizeof(win10));
|
||||
|
||||
test_get_bcd_title_one("test-bcd/description-bad-type.bcd.zst", NULL, 0);
|
||||
test_get_bcd_title_one("test-bcd/description-empty.bcd.zst", NULL, 0);
|
||||
test_get_bcd_title_one("test-bcd/description-missing.bcd.zst", NULL, 0);
|
||||
test_get_bcd_title_one("test-bcd/description-too-small.bcd.zst", NULL, 0);
|
||||
test_get_bcd_title_one("test-bcd/displayorder-bad-name.bcd.zst", NULL, 0);
|
||||
test_get_bcd_title_one("test-bcd/displayorder-bad-size.bcd.zst", NULL, 0);
|
||||
test_get_bcd_title_one("test-bcd/displayorder-bad-type.bcd.zst", NULL, 0);
|
||||
test_get_bcd_title_one("test-bcd/empty.bcd.zst", NULL, 0);
|
||||
}
|
||||
|
||||
TEST(base_block) {
|
||||
size_t len;
|
||||
BaseBlock backup;
|
||||
uint8_t *bcd_base;
|
||||
_cleanup_free_ BaseBlock *bcd = NULL;
|
||||
|
||||
load_bcd("test-bcd/win10.bcd.zst", (void **) &bcd, &len);
|
||||
backup = *bcd;
|
||||
bcd_base = (uint8_t *) bcd;
|
||||
|
||||
assert_se(get_bcd_title(bcd_base, len));
|
||||
|
||||
/* Try various "corruptions" of the base block. */
|
||||
|
||||
assert_se(!get_bcd_title(bcd_base, sizeof(BaseBlock) - 1));
|
||||
|
||||
bcd->sig = 0;
|
||||
assert_se(!get_bcd_title(bcd_base, len));
|
||||
*bcd = backup;
|
||||
|
||||
bcd->version_minor = 2;
|
||||
assert_se(!get_bcd_title(bcd_base, len));
|
||||
*bcd = backup;
|
||||
|
||||
bcd->version_major = 4;
|
||||
assert_se(!get_bcd_title(bcd_base, len));
|
||||
*bcd = backup;
|
||||
|
||||
bcd->type = 1;
|
||||
assert_se(!get_bcd_title(bcd_base, len));
|
||||
*bcd = backup;
|
||||
|
||||
bcd->primary_seqnum++;
|
||||
assert_se(!get_bcd_title(bcd_base, len));
|
||||
*bcd = backup;
|
||||
}
|
||||
|
||||
TEST(bad_bcd) {
|
||||
size_t len;
|
||||
uint8_t *hbins;
|
||||
uint32_t offset;
|
||||
_cleanup_free_ void *bcd = NULL;
|
||||
|
||||
/* This BCD hive has been manipulated to have bad offsets/sizes at various places. */
|
||||
load_bcd("test-bcd/corrupt.bcd.zst", &bcd, &len);
|
||||
|
||||
assert_se(len >= HIVE_CELL_OFFSET);
|
||||
hbins = (uint8_t *) bcd + HIVE_CELL_OFFSET;
|
||||
len -= HIVE_CELL_OFFSET;
|
||||
offset = ((BaseBlock *) bcd)->root_cell_offset;
|
||||
|
||||
const Key *root = get_key(hbins, len, offset, "\0");
|
||||
assert_se(root);
|
||||
assert_se(!get_key(hbins, sizeof(Key) - 1, offset, "\0"));
|
||||
|
||||
assert_se(!get_key(hbins, len, offset, "\0BadOffset\0"));
|
||||
assert_se(!get_key(hbins, len, offset, "\0BadSig\0"));
|
||||
assert_se(!get_key(hbins, len, offset, "\0BadKeyNameLen\0"));
|
||||
assert_se(!get_key(hbins, len, offset, "\0SubkeyBadOffset\0Dummy\0"));
|
||||
assert_se(!get_key(hbins, len, offset, "\0SubkeyBadSig\0Dummy\0"));
|
||||
assert_se(!get_key(hbins, len, offset, "\0SubkeyBadNEntries\0Dummy\0"));
|
||||
|
||||
assert_se(!get_key_value(hbins, len, root, "Dummy"));
|
||||
|
||||
const Key *kv_bad_offset = get_key(hbins, len, offset, "\0KeyValuesBadOffset\0");
|
||||
assert_se(kv_bad_offset);
|
||||
assert_se(!get_key_value(hbins, len, kv_bad_offset, "Dummy"));
|
||||
|
||||
const Key *kv_bad_n_key_values = get_key(hbins, len, offset, "\0KeyValuesBadNKeyValues\0");
|
||||
assert_se(kv_bad_n_key_values);
|
||||
assert_se(!get_key_value(hbins, len, kv_bad_n_key_values, "Dummy"));
|
||||
|
||||
const Key *kv = get_key(hbins, len, offset, "\0KeyValues\0");
|
||||
assert_se(kv);
|
||||
|
||||
assert_se(!get_key_value(hbins, len, kv, "BadOffset"));
|
||||
assert_se(!get_key_value(hbins, len, kv, "BadSig"));
|
||||
assert_se(!get_key_value(hbins, len, kv, "BadNameLen"));
|
||||
assert_se(!get_key_value(hbins, len, kv, "InlineData"));
|
||||
assert_se(!get_key_value(hbins, len, kv, "BadDataOffset"));
|
||||
assert_se(!get_key_value(hbins, len, kv, "BadDataSize"));
|
||||
}
|
||||
|
||||
TEST(argv_bcds) {
|
||||
for (int i = 1; i < saved_argc; i++) {
|
||||
size_t len;
|
||||
_cleanup_free_ void *bcd = NULL;
|
||||
|
||||
assert_se(read_full_file_full(
|
||||
AT_FDCWD,
|
||||
saved_argv[i],
|
||||
UINT64_MAX,
|
||||
SIZE_MAX,
|
||||
0,
|
||||
NULL,
|
||||
(char **) &bcd,
|
||||
&len) >= 0);
|
||||
|
||||
char16_t *title = get_bcd_title(bcd, len);
|
||||
if (title) {
|
||||
_cleanup_free_ char *title_utf8 = utf16_to_utf8(title, char16_strlen(title) * 2);
|
||||
log_info("%s: \"%s\"", saved_argv[i], title_utf8);
|
||||
} else
|
||||
log_info("%s: Bad BCD", saved_argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_TEST_MAIN(LOG_INFO);
|
@ -67,6 +67,11 @@ if install_tests
|
||||
'../-.mount',
|
||||
testsuite08_dir + '/local-fs.target.wants/-.mount')
|
||||
|
||||
if conf.get('HAVE_GNU_EFI') == 1 and conf.get('HAVE_ZSTD') == 1
|
||||
install_subdir('test-bcd',
|
||||
exclude_files : '.gitattributes',
|
||||
install_dir : testdata_dir)
|
||||
endif
|
||||
if conf.get('ENABLE_RESOLVE') == 1
|
||||
install_subdir('test-resolve',
|
||||
exclude_files : '.gitattributes',
|
||||
|
2
test/test-bcd/.gitattributes
vendored
Normal file
2
test/test-bcd/.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*.bcd binary
|
||||
*.bcd.zst binary
|
BIN
test/test-bcd/corrupt.bcd.zst
Normal file
BIN
test/test-bcd/corrupt.bcd.zst
Normal file
Binary file not shown.
BIN
test/test-bcd/description-bad-type.bcd.zst
Normal file
BIN
test/test-bcd/description-bad-type.bcd.zst
Normal file
Binary file not shown.
BIN
test/test-bcd/description-empty.bcd.zst
Normal file
BIN
test/test-bcd/description-empty.bcd.zst
Normal file
Binary file not shown.
BIN
test/test-bcd/description-missing.bcd.zst
Normal file
BIN
test/test-bcd/description-missing.bcd.zst
Normal file
Binary file not shown.
BIN
test/test-bcd/description-too-small.bcd.zst
Normal file
BIN
test/test-bcd/description-too-small.bcd.zst
Normal file
Binary file not shown.
BIN
test/test-bcd/displayorder-bad-name.bcd.zst
Normal file
BIN
test/test-bcd/displayorder-bad-name.bcd.zst
Normal file
Binary file not shown.
BIN
test/test-bcd/displayorder-bad-size.bcd.zst
Normal file
BIN
test/test-bcd/displayorder-bad-size.bcd.zst
Normal file
Binary file not shown.
BIN
test/test-bcd/displayorder-bad-type.bcd.zst
Normal file
BIN
test/test-bcd/displayorder-bad-type.bcd.zst
Normal file
Binary file not shown.
BIN
test/test-bcd/empty.bcd.zst
Normal file
BIN
test/test-bcd/empty.bcd.zst
Normal file
Binary file not shown.
BIN
test/test-bcd/win10.bcd.zst
Normal file
BIN
test/test-bcd/win10.bcd.zst
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user