]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
chid-fundamental: not all SMBIOS fields are available on all systems
authorLennart Poettering <lennart@poettering.net>
Fri, 20 Dec 2024 11:02:33 +0000 (12:02 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 20 Dec 2024 17:06:34 +0000 (18:06 +0100)
And the CHID documentation says that CHIDs that require fields that are
not available on the local system should not be generated. Follow that,
and generate a NULL CHID in that case (which we generally ignore
otherwise).

src/fundamental/chid-fundamental.c

index 9c719a334dd426e8f266f78f9b6e1ec70940644a..ab366ca8ee4bca1c0b32a486e184bce86dedb501 100644 (file)
 #include "memory-util-fundamental.h"
 #include "sha1-fundamental.h"
 
-static void get_chid(const char16_t *const smbios_fields[static _CHID_SMBIOS_FIELDS_MAX], uint32_t mask, EFI_GUID *ret_chid) {
+static void get_chid(
+                const char16_t *const smbios_fields[static _CHID_SMBIOS_FIELDS_MAX],
+                uint32_t mask,
+                EFI_GUID *ret_chid) {
+
         assert(mask != 0);
         assert(ret_chid);
         const EFI_GUID namespace = { UINT32_C(0x12d8ff70), UINT16_C(0x7f4c), UINT16_C(0x7d4c), {} }; /* Swapped to BE */
@@ -38,13 +42,22 @@ static void get_chid(const char16_t *const smbios_fields[static _CHID_SMBIOS_FIE
 
         sha1_process_bytes(&namespace, sizeof(namespace), &ctx);
 
-        for (unsigned i = 0; i < _CHID_SMBIOS_FIELDS_MAX; i++)
-                if ((mask >> i) & 1) {
-                        if (i > 0)
-                                sha1_process_bytes(L"&", 2, &ctx);
-                        sha1_process_bytes(smbios_fields[i], strlen16(smbios_fields[i]) * sizeof(char16_t), &ctx);
+        for (unsigned i = 0; i < _CHID_SMBIOS_FIELDS_MAX; i++) {
+                if (!((mask >> i) & 1))
+                        continue;
+
+                if (!smbios_fields[i]) {
+                        /* If some SMBIOS field is missing, don't generate the CHID, as per spec */
+                        memzero(ret_chid, sizeof(EFI_GUID));
+                        return;
                 }
 
+                if (i > 0)
+                        sha1_process_bytes(L"&", 2, &ctx);
+
+                sha1_process_bytes(smbios_fields[i], strlen16(smbios_fields[i]) * sizeof(char16_t), &ctx);
+        }
+
         uint8_t hash[SHA1_DIGEST_SIZE];
         sha1_finish_ctx(&ctx, hash);
 
@@ -111,9 +124,12 @@ void chid_calculate(const char16_t *const smbios_fields[static _CHID_SMBIOS_FIEL
         assert(smbios_fields);
         assert(ret_chids);
 
-        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
+        for (size_t i = 0; i < CHID_TYPES_MAX; i++) {
+                if (chid_smbios_table[i] == 0) {
                         memzero(&ret_chids[i], sizeof(EFI_GUID));
+                        continue;
+                }
+
+                get_chid(smbios_fields, chid_smbios_table[i], &ret_chids[i]);
+        }
 }