Skip to content

Commit

Permalink
Various multi-dt fixes and CHID test (systemd#35056)
Browse files Browse the repository at this point in the history
  • Loading branch information
yuwata authored Nov 10, 2024
2 parents 8254755 + 310997d commit cf8fd71
Show file tree
Hide file tree
Showing 9 changed files with 131 additions and 10 deletions.
6 changes: 3 additions & 3 deletions src/boot/chid.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ static char16_t *smbios_to_hashable_string(const char *str) {

/* This has to be in a struct due to _cleanup_ in populate_board_chids */
typedef struct SmbiosInfo {
const char16_t *smbios_fields[_CHID_SMBIOS_FIELDS_MAX];
char16_t *smbios_fields[_CHID_SMBIOS_FIELDS_MAX];
} SmbiosInfo;

static void smbios_info_populate(SmbiosInfo *ret_info) {
Expand All @@ -71,7 +71,7 @@ static void smbios_info_populate(SmbiosInfo *ret_info) {

static void smbios_info_done(SmbiosInfo *info) {
FOREACH_ELEMENT(i, info->smbios_fields)
free(i);
free(*i);
}

static EFI_STATUS populate_board_chids(EFI_GUID ret_chids[static CHID_TYPES_MAX]) {
Expand All @@ -81,7 +81,7 @@ static EFI_STATUS populate_board_chids(EFI_GUID ret_chids[static CHID_TYPES_MAX]
return EFI_INVALID_PARAMETER;

smbios_info_populate(&info);
chid_calculate(info.smbios_fields, ret_chids);
chid_calculate((const char16_t *const *) info.smbios_fields, ret_chids);

return EFI_SUCCESS;
}
Expand Down
3 changes: 2 additions & 1 deletion src/boot/devicetree.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ static const char* devicetree_get_compatible(const void *dtb) {

if (struct_off % sizeof(uint32_t) != 0)
return NULL;

if (struct_size % sizeof(uint32_t) != 0 ||
!ADD_SAFE(&end, struct_off, struct_size) ||
end > strings_off)
Expand All @@ -150,7 +151,7 @@ static const char* devicetree_get_compatible(const void *dtb) {
break;
case FDT_PROP:
/* At least 3 words should present: len, name_off, c (nul-terminated string always has non-zero length) */
if (i + 3 >= size_words || cursor[++i] != 0)
if (i + 3 >= size_words)
return NULL;
len = be32toh(cursor[++i]);
name_off = be32toh(cursor[++i]);
Expand Down
2 changes: 1 addition & 1 deletion src/boot/pe.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ static void pe_locate_sections_internal(
j->VirtualSize,
device_table,
device,
i))
(PTR_TO_SIZE(j) - PTR_TO_SIZE(section_table)) / sizeof(*j)))
continue;
}

Expand Down
9 changes: 4 additions & 5 deletions src/fundamental/chid-fundamental.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,12 @@
*/

#if SD_BOOT
# include "efi-string.h"
# include "util.h"
#else
# include <byteswap.h>
# include <string.h>
# include <uchar.h>
# include <utf8.h>
#define strsize16(str) ((char16_strlen(str) + 1) * sizeof(char16_t))
#define strlen16 char16_strlen
#endif

#include "chid-fundamental.h"
Expand All @@ -44,7 +42,7 @@ static void get_chid(const char16_t *const smbios_fields[static _CHID_SMBIOS_FIE
if ((mask >> i) & 1) {
if (i > 0)
sha1_process_bytes(L"&", 2, &ctx);
sha1_process_bytes(smbios_fields[i], strsize16(smbios_fields[i]), &ctx);
sha1_process_bytes(smbios_fields[i], strlen16(smbios_fields[i]) * sizeof(char16_t), &ctx);
}

uint8_t hash[SHA1_DIGEST_SIZE];
Expand Down Expand Up @@ -112,7 +110,8 @@ static const uint32_t chid_smbios_table[CHID_TYPES_MAX] = {
void chid_calculate(const char16_t *const smbios_fields[static _CHID_SMBIOS_FIELDS_MAX], EFI_GUID ret_chids[static CHID_TYPES_MAX]) {
assert(smbios_fields);
assert(ret_chids);
for (size_t i = 0; i < _CHID_SMBIOS_FIELDS_MAX; i++)

for (size_t i = 0; i < CHID_TYPES_MAX; i++)
if (chid_smbios_table[i] != 0)
get_chid(smbios_fields, chid_smbios_table[i], &ret_chids[i]);
else
Expand Down
6 changes: 6 additions & 0 deletions src/fundamental/chid-fundamental.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

#pragma once

#if SD_BOOT
# include "efi-string.h"
#else
# include <uchar.h>
#endif

#include "efi-fundamental.h"
#include "string-util-fundamental.h"

Expand Down
7 changes: 7 additions & 0 deletions src/fundamental/efi-fundamental.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
#pragma once

#if !SD_BOOT
# include <stdbool.h>
# include <stdint.h>
# include <string.h>

/* Matches EFI API definition of the same structure for userspace */
typedef struct {
uint32_t Data1;
Expand All @@ -11,6 +14,10 @@ typedef struct {
uint8_t Data4[8];
} EFI_GUID;

static inline bool efi_guid_equal(const EFI_GUID *a, const EFI_GUID *b) {
return memcmp(a, b, sizeof(EFI_GUID)) == 0;
}

typedef struct {
EFI_GUID SignatureOwner;
uint8_t SignatureData[];
Expand Down
19 changes: 19 additions & 0 deletions src/shared/tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -559,3 +559,22 @@ static inline int run_test_table(void) {
abort(); \
} \
})

#define EFI_GUID_Fmt "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"
#define EFI_GUID_Arg(guid) (guid).Data1, (guid).Data2, (guid).Data3, \
(guid).Data4[0], (guid).Data4[1], (guid).Data4[2], (guid).Data4[3], \
(guid).Data4[4], (guid).Data4[5], (guid).Data4[6], (guid).Data4[7] \

#define ASSERT_EQ_EFI_GUID(expr1, expr2) \
({ \
typeof(expr1) _expr1 = (expr1); \
typeof(expr2) _expr2 = (expr2); \
if (!efi_guid_equal(_expr1, _expr2)) { \
log_error("%s:%i: Assertion failed: expected \"%s == %s\", but " EFI_GUID_Fmt \
" != " EFI_GUID_Fmt, \
PROJECT_FILE, __LINE__, \
#expr1, #expr2, \
EFI_GUID_Arg(*_expr1), EFI_GUID_Arg(*_expr2)); \
abort(); \
} \
})
1 change: 1 addition & 0 deletions src/test/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ simple_tests += files(
'test-cgroup-util.c',
'test-cgroup.c',
'test-chase.c',
'test-chid.c',
'test-clock.c',
'test-color-util.c',
'test-compare-operator.c',
Expand Down
88 changes: 88 additions & 0 deletions src/test/test-chid.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include "chid-fundamental.h"
#include "string-util.h"
#include "tests.h"

const char16_t *const test_fields[_CHID_SMBIOS_FIELDS_MAX] = {
[CHID_SMBIOS_MANUFACTURER] = u"Micro-Star International Co., Ltd.",
[CHID_SMBIOS_PRODUCT_NAME] = u"MS-7D70",
[CHID_SMBIOS_PRODUCT_SKU] = u"To be filled by O.E.M.",
[CHID_SMBIOS_FAMILY] = u"To be filled by O.E.M.",
[CHID_SMBIOS_BASEBOARD_PRODUCT] = u"MPG X670E CARBON WIFI (MS-7D70)",
[CHID_SMBIOS_BASEBOARD_MANUFACTURER] = u"Micro-Star International Co., Ltd.",
};

/* Actual output of `fwupdtool hwids`:
BiosVendor: American Megatrends International, LLC.
BiosVersion: 1.E5
BiosMajorRelease: 5
BiosMinorRelease: 32
FirmwareMajorRelease: ff
FirmwareMinorRelease: ff
Manufacturer: Micro-Star International Co., Ltd.
Family: To be filled by O.E.M.
ProductName: MS-7D70
ProductSku: To be filled by O.E.M.
EnclosureKind: 3
BaseboardManufacturer: Micro-Star International Co., Ltd.
BaseboardProduct: MPG X670E CARBON WIFI (MS-7D70)
Hardware IDs
------------
{f59668ca-22bc-52a0-b6b5-1f6ce81b08e0} <- Manufacturer + Family + ProductName + ProductSku + BiosVendor + BiosVersion + BiosMajorRelease + BiosMinorRelease
{f735f7a0-40da-5bfe-8ac2-0090532ee6d0} <- Manufacturer + Family + ProductName + BiosVendor + BiosVersion + BiosMajorRelease + BiosMinorRelease
{25880e68-e005-5ca7-88b6-650de596604f} <- Manufacturer + ProductName + BiosVendor + BiosVersion + BiosMajorRelease + BiosMinorRelease
{01e09b32-de05-56ca-b9d1-9486ad5f381d} <- Manufacturer + Family + ProductName + ProductSku + BaseboardManufacturer + BaseboardProduct
{cad87a11-1813-507b-9aab-9a5f457b649c} <- Manufacturer + Family + ProductName + ProductSku
{377c823d-60d1-55b0-9678-76cd2af9d086} <- Manufacturer + Family + ProductName
{28ac9cf2-5bde-59f7-aebe-4b3d008090fe} <- Manufacturer + ProductSku + BaseboardManufacturer + BaseboardProduct
{e821e0e2-e11a-5e94-bf5d-ffe53c5e5048} <- Manufacturer + ProductSku
{1c092f1d-dc7b-564f-8a3d-128d7292fab8} <- Manufacturer + ProductName + BaseboardManufacturer + BaseboardProduct
{c12c1f4a-332d-5d72-aa36-7a3d413b479a} <- Manufacturer + ProductName
{28ac9cf2-5bde-59f7-aebe-4b3d008090fe} <- Manufacturer + Family + BaseboardManufacturer + BaseboardProduct
{e821e0e2-e11a-5e94-bf5d-ffe53c5e5048} <- Manufacturer + Family
{bdd76d3e-147f-58a9-a0b2-42136454ed07} <- Manufacturer + EnclosureKind
{b2e58e8b-fb10-5cd0-8fb0-5bd931f1871a} <- Manufacturer + BaseboardManufacturer + BaseboardProduct
{50af5797-a2f2-58b1-9a1a-453bcbb2e025} <- Manufacturer
Extra Hardware IDs
------------------
{e6ff1b45-1955-5701-89ab-04fe2280cb4a} <- Manufacturer + Family + ProductName + ProductSku + BiosVendor
{8c4a76b9-e29e-5a3c-9072-9664898ecae6} <- Manufacturer + Family + ProductName + BiosVendor
{7b3d90ce-ed79-5951-a48a-764ea9f11146} <- Manufacturer + BiosVendor
*/

static const EFI_GUID actual_chids[] = {
{0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{0x01e09b32, 0xde05, 0x56ca, {0xb9, 0xd1, 0x94, 0x86, 0xad, 0x5f, 0x38, 0x1d}},
{0xcad87a11, 0x1813, 0x507b, {0x9a, 0xab, 0x9a, 0x5f, 0x45, 0x7b, 0x64, 0x9c}},
{0x377c823d, 0x60d1, 0x55b0, {0x96, 0x78, 0x76, 0xcd, 0x2a, 0xf9, 0xd0, 0x86}},
{0x28ac9cf2, 0x5bde, 0x59f7, {0xae, 0xbe, 0x4b, 0x3d, 0x00, 0x80, 0x90, 0xfe}},
{0xe821e0e2, 0xe11a, 0x5e94, {0xbf, 0x5d, 0xff, 0xe5, 0x3c, 0x5e, 0x50, 0x48}},
{0x1c092f1d, 0xdc7b, 0x564f, {0x8a, 0x3d, 0x12, 0x8d, 0x72, 0x92, 0xfa, 0xb8}},
{0xc12c1f4a, 0x332d, 0x5d72, {0xaa, 0x36, 0x7a, 0x3d, 0x41, 0x3b, 0x47, 0x9a}},
{0x28ac9cf2, 0x5bde, 0x59f7, {0xae, 0xbe, 0x4b, 0x3d, 0x00, 0x80, 0x90, 0xfe}},
{0xe821e0e2, 0xe11a, 0x5e94, {0xbf, 0x5d, 0xff, 0xe5, 0x3c, 0x5e, 0x50, 0x48}},
{0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
{0xb2e58e8b, 0xfb10, 0x5cd0, {0x8f, 0xb0, 0x5b, 0xd9, 0x31, 0xf1, 0x87, 0x1a}},
{0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
};

TEST(chid) {
/* Results compared with output of 'fwupdtool hwids' */
EFI_GUID chids[CHID_TYPES_MAX];
chid_calculate(test_fields, chids);
for (size_t i = 0; i < ELEMENTSOF(chids); i++)
ASSERT_EQ_EFI_GUID(&chids[i], &actual_chids[i]);
}

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);

0 comments on commit cf8fd71

Please sign in to comment.