test: Add CHID matching test (#35532)
This commit is contained in:
@@ -37,7 +37,7 @@ jobs:
|
||||
VALIDATE_GITHUB_ACTIONS: true
|
||||
|
||||
- name: Check that tabs are not used in Python code
|
||||
run: sh -c '! git grep -P "\\t" -- src/ukify/ukify.py test/integration-test-wrapper.py'
|
||||
run: sh -c '! git grep -P "\\t" -- src/boot/generate-hwids-section.py src/ukify/ukify.py test/integration-test-wrapper.py'
|
||||
|
||||
- name: Install ruff and mypy
|
||||
run: |
|
||||
@@ -47,14 +47,14 @@ jobs:
|
||||
- name: Run mypy
|
||||
run: |
|
||||
python3 -m mypy --version
|
||||
python3 -m mypy src/test/generate-sym-test.py src/ukify/ukify.py test/integration-test-wrapper.py
|
||||
python3 -m mypy src/boot/generate-hwids-section.py src/test/generate-sym-test.py src/ukify/ukify.py test/integration-test-wrapper.py
|
||||
|
||||
- name: Run ruff check
|
||||
run: |
|
||||
ruff --version
|
||||
ruff check src/test/generate-sym-test.py src/ukify/ukify.py test/integration-test-wrapper.py
|
||||
ruff check src/boot/generate-hwids-section.py src/test/generate-sym-test.py src/ukify/ukify.py test/integration-test-wrapper.py
|
||||
|
||||
- name: Run ruff format
|
||||
run: |
|
||||
ruff --version
|
||||
ruff format --check src/test/generate-sym-test.py src/ukify/ukify.py test/integration-test-wrapper.py
|
||||
ruff format --check src/boot/generate-hwids-section.py src/test/generate-sym-test.py src/ukify/ukify.py test/integration-test-wrapper.py
|
||||
|
||||
+7
-6
@@ -58,13 +58,10 @@ typedef struct SmbiosInfo {
|
||||
} SmbiosInfo;
|
||||
|
||||
static void smbios_info_populate(SmbiosInfo *ret_info) {
|
||||
static RawSmbiosInfo raw = {};
|
||||
static bool raw_info_populated = false;
|
||||
assert(ret_info);
|
||||
|
||||
if (!raw_info_populated) {
|
||||
smbios_raw_info_populate(&raw);
|
||||
raw_info_populated = true;
|
||||
}
|
||||
RawSmbiosInfo raw;
|
||||
smbios_raw_info_get_cached(&raw);
|
||||
|
||||
ret_info->smbios_fields[CHID_SMBIOS_MANUFACTURER] = smbios_to_hashable_string(raw.manufacturer);
|
||||
ret_info->smbios_fields[CHID_SMBIOS_PRODUCT_NAME] = smbios_to_hashable_string(raw.product_name);
|
||||
@@ -104,7 +101,11 @@ EFI_STATUS chid_match(const void *hwid_buffer, size_t hwid_length, const Device
|
||||
|
||||
status = populate_board_chids(chids);
|
||||
if (EFI_STATUS_IS_ERROR(status))
|
||||
#if SD_BOOT
|
||||
return log_error_status(status, "Failed to populate board CHIDs: %m");
|
||||
#else
|
||||
return status;
|
||||
#endif
|
||||
|
||||
size_t n_devices = 0;
|
||||
|
||||
|
||||
+1
-33
@@ -6,6 +6,7 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "efi-fundamental.h"
|
||||
#include "macro-fundamental.h"
|
||||
|
||||
#if SD_BOOT
|
||||
@@ -118,30 +119,11 @@ typedef uint64_t EFI_PHYSICAL_ADDRESS;
|
||||
#define EFI_IP_ADDRESS_CONFLICT EFIERR(34)
|
||||
#define EFI_HTTP_ERROR EFIERR(35)
|
||||
|
||||
typedef struct {
|
||||
uint32_t Data1;
|
||||
uint16_t Data2;
|
||||
uint16_t Data3;
|
||||
uint8_t Data4[8];
|
||||
} EFI_GUID;
|
||||
|
||||
#define GUID_DEF(d1, d2, d3, d4_1, d4_2, d4_3, d4_4, d4_5, d4_6, d4_7, d4_8) \
|
||||
{ d1, d2, d3, { d4_1, d4_2, d4_3, d4_4, d4_5, d4_6, d4_7, d4_8 } }
|
||||
|
||||
/* Creates a EFI_GUID pointer suitable for EFI APIs. Use of const allows the compiler to merge multiple
|
||||
* uses (although, currently compilers do that regardless). Most EFI APIs declare their EFI_GUID input
|
||||
* as non-const, but almost all of them are in fact const. */
|
||||
#define MAKE_GUID_PTR(name) ((EFI_GUID *) &(const EFI_GUID) name##_GUID)
|
||||
|
||||
/* These allow MAKE_GUID_PTR() to work without requiring an extra _GUID in the passed name. We want to
|
||||
* keep the GUID definitions in line with the UEFI spec. */
|
||||
#define EFI_GLOBAL_VARIABLE_GUID EFI_GLOBAL_VARIABLE
|
||||
#define EFI_FILE_INFO_GUID EFI_FILE_INFO_ID
|
||||
|
||||
#define EFI_GLOBAL_VARIABLE \
|
||||
GUID_DEF(0x8be4df61, 0x93ca, 0x11d2, 0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c)
|
||||
#define EFI_IMAGE_SECURITY_DATABASE_GUID \
|
||||
GUID_DEF(0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f)
|
||||
#define EFI_CUSTOM_MODE_ENABLE_GUID \
|
||||
GUID_DEF(0xc076ec0c, 0x7028, 0x4399, 0xa0, 0x72, 0x71, 0xee, 0x5c, 0x44, 0x8b, 0x9f)
|
||||
|
||||
@@ -238,20 +220,6 @@ typedef enum {
|
||||
EfiResetPlatformSpecific,
|
||||
} EFI_RESET_TYPE;
|
||||
|
||||
typedef struct {
|
||||
uint16_t Year;
|
||||
uint8_t Month;
|
||||
uint8_t Day;
|
||||
uint8_t Hour;
|
||||
uint8_t Minute;
|
||||
uint8_t Second;
|
||||
uint8_t Pad1;
|
||||
uint32_t Nanosecond;
|
||||
int16_t TimeZone;
|
||||
uint8_t Daylight;
|
||||
uint8_t Pad2;
|
||||
} EFI_TIME;
|
||||
|
||||
typedef struct {
|
||||
uint32_t Resolution;
|
||||
uint32_t Accuracy;
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# We import ukify.py, which is a template file. But only __version__ is
|
||||
# substituted, which we don't care about here. Having the .py suffix makes it
|
||||
# easier to import the file.
|
||||
sys.path.append(os.path.dirname(__file__) + '/../ukify')
|
||||
import ukify
|
||||
|
||||
BYTES_PER_LINE = 16
|
||||
|
||||
hwids = ukify.parse_hwid_dir(Path(sys.argv[1]))
|
||||
|
||||
print(
|
||||
"""/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
const uint8_t hwids_section_data[] = {
|
||||
""",
|
||||
end='',
|
||||
)
|
||||
|
||||
for i, b in enumerate(hwids):
|
||||
print(f'0x{b:02X}, ', end='')
|
||||
if i % BYTES_PER_LINE == BYTES_PER_LINE - 1:
|
||||
print('\n ', end='')
|
||||
elif i == len(hwids) - 1:
|
||||
print('')
|
||||
|
||||
print(
|
||||
"""};
|
||||
const size_t hwids_section_len =""",
|
||||
f'{len(hwids)};',
|
||||
)
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "Device 1",
|
||||
"compatible": "test,device-1",
|
||||
"hwids": [
|
||||
"2bdcafa9-727c-5e8b-b13b-236f1391c25a",
|
||||
"c87886da-8026-5149-8c95-6d2504c1b7f9"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "Device 2",
|
||||
"compatible": "test,device-2",
|
||||
"hwids": [
|
||||
"6ff16153-a32f-548a-9cd7-3574a5d0caa4",
|
||||
"0afb4762-c5bb-5fba-887b-d56ce73ee793"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "Device 3",
|
||||
"compatible": "test,device-3",
|
||||
"hwids": [
|
||||
"06b74502-e5d8-5ecd-a67a-e77654cf3b17",
|
||||
"a8d84e4e-23d9-5629-86da-a49d859b5cde"
|
||||
]
|
||||
}
|
||||
@@ -7,6 +7,7 @@ libefitest = static_library(
|
||||
'efitest',
|
||||
files(
|
||||
'bcd.c',
|
||||
'chid.c',
|
||||
'efi-string.c',
|
||||
),
|
||||
build_by_default : false,
|
||||
@@ -25,6 +26,16 @@ efitest_base = {
|
||||
efi_test_template = test_template + efitest_base
|
||||
efi_fuzz_template = fuzz_template + efitest_base
|
||||
|
||||
generate_hwids_section_py = find_program('generate-hwids-section.py')
|
||||
|
||||
test_hwids_section_c = custom_target(
|
||||
'test-hwids-section.c',
|
||||
input : ['hwids/device1.json', 'hwids/device2.json', 'hwids/device2.json'],
|
||||
output : 'test-hwids-section.c',
|
||||
command : [generate_hwids_section_py, meson.current_source_dir()/'hwids'],
|
||||
capture : true,
|
||||
build_by_default : want_tests != 'false')
|
||||
|
||||
executables += [
|
||||
efi_test_template + {
|
||||
'sources' : files('test-bcd.c'),
|
||||
@@ -35,6 +46,11 @@ executables += [
|
||||
'sources' : files('test-efi-string.c'),
|
||||
'conditions' : ['ENABLE_BOOTLOADER'],
|
||||
},
|
||||
efi_test_template + {
|
||||
'sources' : files('test-chid-match.c') +
|
||||
test_hwids_section_c,
|
||||
'conditions' : ['ENABLE_BOOTLOADER'],
|
||||
},
|
||||
efi_fuzz_template + {
|
||||
'sources' : files('fuzz-bcd.c'),
|
||||
},
|
||||
|
||||
@@ -259,3 +259,17 @@ void smbios_raw_info_populate(RawSmbiosInfo *ret_info) {
|
||||
ret_info->baseboard_product = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void smbios_raw_info_get_cached(RawSmbiosInfo *ret_info) {
|
||||
static RawSmbiosInfo info = {};
|
||||
static bool cached = false;
|
||||
|
||||
assert(ret_info);
|
||||
|
||||
if (!cached) {
|
||||
smbios_raw_info_populate(&info);
|
||||
cached = true;
|
||||
}
|
||||
|
||||
*ret_info = info;
|
||||
}
|
||||
|
||||
@@ -17,3 +17,4 @@ typedef struct RawSmbiosInfo {
|
||||
} RawSmbiosInfo;
|
||||
|
||||
void smbios_raw_info_populate(RawSmbiosInfo *ret_info);
|
||||
void smbios_raw_info_get_cached(RawSmbiosInfo *ret_info);
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "chid.h"
|
||||
#include "smbios.h"
|
||||
#include "tests.h"
|
||||
|
||||
extern uint8_t hwids_section_data[];
|
||||
extern size_t hwids_section_len;
|
||||
|
||||
static const RawSmbiosInfo smbios_info[] = {
|
||||
{
|
||||
.manufacturer = "First Vendor",
|
||||
.product_name = "Device 1",
|
||||
.product_sku = "KD01",
|
||||
.family = "Laptop X",
|
||||
.baseboard_product = "FODM1",
|
||||
.baseboard_manufacturer = "First ODM",
|
||||
},
|
||||
{
|
||||
.manufacturer = "Second Vendor",
|
||||
.product_name = "Device 2",
|
||||
.product_sku = "KD02",
|
||||
.family = "Laptop 2",
|
||||
.baseboard_product = "SODM2",
|
||||
.baseboard_manufacturer = "Second ODM",
|
||||
},
|
||||
{
|
||||
.manufacturer = "First Vendor",
|
||||
.product_name = "Device 3",
|
||||
.product_sku = "KD03",
|
||||
.family = "Tablet Y",
|
||||
.baseboard_product = "FODM2",
|
||||
.baseboard_manufacturer = "First ODM",
|
||||
},
|
||||
};
|
||||
|
||||
static struct {
|
||||
const char *name;
|
||||
const char *compatible;
|
||||
} results[] = {
|
||||
{ "Device 1", "test,device-1" },
|
||||
{ "Device 2", "test,device-2" },
|
||||
{ "Device 3", "test,device-3" },
|
||||
};
|
||||
|
||||
static RawSmbiosInfo current_info = {};
|
||||
|
||||
/* This is a dummy implementation for testing purposes */
|
||||
void smbios_raw_info_get_cached(RawSmbiosInfo *ret_info) {
|
||||
assert(ret_info);
|
||||
*ret_info = current_info;
|
||||
}
|
||||
|
||||
TEST(chid_match) {
|
||||
for (size_t i = 0; i < ELEMENTSOF(smbios_info); i++) {
|
||||
current_info = smbios_info[i];
|
||||
const Device *dev = NULL;
|
||||
/* Match and check */
|
||||
ASSERT_EQ(chid_match(hwids_section_data, hwids_section_len, &dev), EFI_SUCCESS);
|
||||
ASSERT_NOT_NULL(dev);
|
||||
ASSERT_STREQ(device_get_name(hwids_section_data, dev), results[i].name);
|
||||
ASSERT_STREQ(device_get_compatible(hwids_section_data, dev), results[i].compatible);
|
||||
}
|
||||
}
|
||||
|
||||
static int intro(void) {
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
return EXIT_SUCCESS;
|
||||
#else
|
||||
return log_tests_skipped("cannot run CHID calculation on big-endian machine");
|
||||
#endif
|
||||
}
|
||||
|
||||
DEFINE_TEST_MAIN_WITH_INTRO(LOG_INFO, intro);
|
||||
+13
-2
@@ -3,11 +3,14 @@
|
||||
|
||||
#include "efi.h"
|
||||
#include "efi-string.h"
|
||||
#include "log.h"
|
||||
#include "memory-util-fundamental.h"
|
||||
#include "proto/file-io.h"
|
||||
#include "string-util-fundamental.h"
|
||||
|
||||
#if SD_BOOT
|
||||
|
||||
#include "log.h"
|
||||
#include "proto/file-io.h"
|
||||
|
||||
/* This is provided by the linker. */
|
||||
extern uint8_t __executable_start[];
|
||||
|
||||
@@ -236,3 +239,11 @@ char16_t *get_extra_dir(const EFI_DEVICE_PATH *file_path);
|
||||
|
||||
#define bswap_16(x) __builtin_bswap16(x)
|
||||
#define bswap_32(x) __builtin_bswap32(x)
|
||||
|
||||
#else
|
||||
|
||||
#include "alloc-util.h"
|
||||
|
||||
#define xnew0(type, n) ASSERT_PTR(new0(type, n))
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#if !SD_BOOT
|
||||
# include <stdbool.h>
|
||||
# include <stdint.h>
|
||||
# include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Matches EFI API definition of the same structure for userspace */
|
||||
typedef struct {
|
||||
@@ -14,9 +11,13 @@ typedef struct {
|
||||
uint8_t Data4[8];
|
||||
} EFI_GUID;
|
||||
|
||||
#if !SD_BOOT
|
||||
# include <stdbool.h>
|
||||
# include <string.h>
|
||||
static inline bool efi_guid_equal(const EFI_GUID *a, const EFI_GUID *b) {
|
||||
return memcmp(a, b, sizeof(EFI_GUID)) == 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
EFI_GUID SignatureOwner;
|
||||
@@ -66,6 +67,9 @@ typedef struct {
|
||||
#define GUID_DEF(d1, d2, d3, d4_1, d4_2, d4_3, d4_4, d4_5, d4_6, d4_7, d4_8) \
|
||||
{ d1, d2, d3, { d4_1, d4_2, d4_3, d4_4, d4_5, d4_6, d4_7, d4_8 } }
|
||||
|
||||
/* Creates a EFI_GUID pointer suitable for EFI APIs. Use of const allows the compiler to merge multiple
|
||||
* uses (although, currently compilers do that regardless). Most EFI APIs declare their EFI_GUID input
|
||||
* as non-const, but almost all of them are in fact const. */
|
||||
#define MAKE_GUID_PTR(name) ((EFI_GUID *) &(const EFI_GUID) name##_GUID)
|
||||
|
||||
#define EFI_GLOBAL_VARIABLE \
|
||||
@@ -77,5 +81,3 @@ typedef struct {
|
||||
GUID_DEF(0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72)
|
||||
#define EFI_CERT_TYPE_PKCS7_GUID \
|
||||
GUID_DEF(0x4aafd29d, 0x68df, 0x49ee, 0x8a, 0xa9, 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7)
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user