• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemd / systemd / 16280725298

14 Jul 2025 08:16PM UTC coverage: 72.166% (-0.006%) from 72.172%
16280725298

push

github

web-flow
Two fixlets for coverage test (#38183)

302135 of 418667 relevant lines covered (72.17%)

773261.64 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

58.02
/src/shared/efi-api.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <unistd.h>
4

5
#include "alloc-util.h"
6
#include "dirent-util.h"
7
#include "efi-api.h"
8
#include "efi-fundamental.h"
9
#include "efivars.h"
10
#include "fd-util.h"
11
#include "fileio.h"
12
#include "log.h"
13
#include "parse-util.h"
14
#include "sort-util.h"
15
#include "stat-util.h"
16
#include "stdio-util.h"
17
#include "string-util.h"
18
#include "utf8.h"
19

20
#define LOAD_OPTION_ACTIVE            0x00000001
21
#define MEDIA_DEVICE_PATH                   0x04
22
#define MEDIA_HARDDRIVE_DP                  0x01
23
#define MEDIA_FILEPATH_DP                   0x04
24
#define SIGNATURE_TYPE_GUID                 0x02
25
#define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02
26
#define END_DEVICE_PATH_TYPE                0x7f
27
#define END_ENTIRE_DEVICE_PATH_SUBTYPE      0xff
28

29
#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI UINT64_C(0x0000000000000001)
30

31
#define boot_option__contents                   \
32
        {                                       \
33
                uint32_t attr;                  \
34
                uint16_t path_len;              \
35
                uint16_t title[];               \
36
        }
37

38
struct boot_option boot_option__contents;
39
struct boot_option__packed boot_option__contents _packed_;
40
assert_cc(offsetof(struct boot_option, title) == offsetof(struct boot_option__packed, title));
41
/* sizeof(struct boot_option) != sizeof(struct boot_option__packed), so
42
 * the *size* of the structure should not be used anywhere below. */
43

44
struct drive_path {
45
        uint32_t part_nr;
46
        uint64_t part_start;
47
        uint64_t part_size;
48
        char signature[16];
49
        uint8_t mbr_type;
50
        uint8_t signature_type;
51
} _packed_;
52

53
#define device_path__contents                           \
54
        {                                               \
55
                uint8_t type;                           \
56
                uint8_t sub_type;                       \
57
                uint16_t length;                        \
58
                union {                                 \
59
                        uint16_t path[0];               \
60
                        struct drive_path drive;        \
61
                };                                      \
62
        }
63

64
struct device_path device_path__contents;
65
struct device_path__packed device_path__contents _packed_;
66
assert_cc(sizeof(struct device_path) == sizeof(struct device_path__packed));
67

68
#if ENABLE_EFI
69
static int get_os_indications(uint64_t *ret) {
9✔
70
        static struct stat cache_stat = {};
9✔
71
        _cleanup_free_ void *v = NULL;
9✔
72
        static uint64_t cache;
9✔
73
        struct stat new_stat;
9✔
74
        size_t s;
9✔
75
        int r;
9✔
76

77
        assert(ret);
9✔
78

79
        /* Let's verify general support first */
80
        r = efi_reboot_to_firmware_supported();
9✔
81
        if (r < 0)
9✔
82
                return r;
83

84
        /* stat() the EFI variable, to see if the mtime changed. If it did we need to cache again. */
85
        if (stat(EFIVAR_PATH(EFI_GLOBAL_VARIABLE_STR("OsIndications")), &new_stat) < 0) {
6✔
86
                if (errno != ENOENT)
6✔
87
                        return -errno;
×
88

89
                /* Doesn't exist? Then we can exit early (also see below) */
90
                *ret = 0;
6✔
91
                return 0;
6✔
92

93
        } else if (stat_inode_unmodified(&new_stat, &cache_stat)) {
×
94
                /* inode didn't change, we can return the cached value */
95
                *ret = cache;
×
96
                return 0;
×
97
        }
98

99
        r = efi_get_variable(EFI_GLOBAL_VARIABLE_STR("OsIndications"), NULL, &v, &s);
×
100
        if (r == -ENOENT) {
×
101
                /* Some firmware implementations that do support OsIndications and report that with
102
                 * OsIndicationsSupported will remove the OsIndications variable when it is unset. Let's
103
                 * pretend it's 0 then, to hide this implementation detail. Note that this call will return
104
                 * -ENOENT then only if the support for OsIndications is missing entirely, as determined by
105
                 * efi_reboot_to_firmware_supported() above. */
106
                *ret = 0;
×
107
                return 0;
×
108
        }
109
        if (r < 0)
×
110
                return r;
111
        if (s != sizeof(uint64_t))
×
112
                return -EINVAL;
113

114
        cache_stat = new_stat;
×
115
        *ret = cache = *(uint64_t *)v;
×
116
        return 0;
×
117
}
118

119
static ssize_t utf16_size(const uint16_t *s, size_t buf_len_bytes) {
12✔
120
        size_t l = 0;
12✔
121

122
        /* Returns the size of the string in bytes without the terminating two zero bytes */
123

124
        while (l < buf_len_bytes / sizeof(uint16_t)) {
138✔
125
                if (s[l] == 0)
138✔
126
                        return (l + 1) * sizeof(uint16_t);
12✔
127
                l++;
126✔
128
        }
129

130
        return -EINVAL; /* The terminator was not found */
131
}
132

133
static void to_utf16(uint16_t *dest, const char *src) {
×
134
        int i;
×
135

136
        for (i = 0; src[i] != '\0'; i++)
×
137
                dest[i] = src[i];
×
138
        dest[i] = '\0';
×
139
}
×
140

141
static uint16_t *tilt_slashes(uint16_t *s) {
×
142
        for (uint16_t *p = s; *p; p++)
×
143
                if (*p == '/')
×
144
                        *p = '\\';
×
145

146
        return s;
×
147
}
148

149
static int boot_id_hex(const char s[static 4]) {
12✔
150
        int id = 0;
12✔
151

152
        assert(s);
12✔
153

154
        for (int i = 0; i < 4; i++)
60✔
155
                if (s[i] >= '0' && s[i] <= '9')
48✔
156
                        id |= (s[i] - '0') << (3 - i) * 4;
48✔
157
                else if (s[i] >= 'A' && s[i] <= 'F')
×
158
                        id |= (s[i] - 'A' + 10) << (3 - i) * 4;
×
159
                else
160
                        return -EINVAL;
161

162
        return id;
163
}
164
#endif
165

166
int efi_reboot_to_firmware_supported(void) {
9✔
167
#if ENABLE_EFI
168
        _cleanup_free_ void *v = NULL;
9✔
169
        static int cache = -1;
9✔
170
        uint64_t b;
9✔
171
        size_t s;
9✔
172
        int r;
9✔
173

174
        if (cache > 0)
9✔
175
                return 0;
176
        if (cache == 0)
9✔
177
                return -EOPNOTSUPP;
178

179
        if (!is_efi_boot())
9✔
180
                goto not_supported;
3✔
181

182
        r = efi_get_variable(EFI_GLOBAL_VARIABLE_STR("OsIndicationsSupported"), NULL, &v, &s);
6✔
183
        if (r == -ENOENT)
6✔
184
                goto not_supported; /* variable doesn't exist? it's not supported then */
×
185
        if (r < 0)
6✔
186
                return r;
187
        if (s != sizeof(uint64_t))
6✔
188
                return -EINVAL;
189

190
        b = *(uint64_t*) v;
6✔
191
        if (!(b & EFI_OS_INDICATIONS_BOOT_TO_FW_UI))
6✔
192
                goto not_supported; /* bit unset? it's not supported then */
×
193

194
        cache = 1;
6✔
195
        return 0;
6✔
196

197
not_supported:
3✔
198
        cache = 0;
3✔
199
        return -EOPNOTSUPP;
3✔
200
#else
201
        return -EOPNOTSUPP;
202
#endif
203
}
204

205
int efi_get_reboot_to_firmware(void) {
7✔
206
#if ENABLE_EFI
207
        int r;
7✔
208
        uint64_t b;
7✔
209

210
        r = get_os_indications(&b);
7✔
211
        if (r < 0)
7✔
212
                return r;
7✔
213

214
        return !!(b & EFI_OS_INDICATIONS_BOOT_TO_FW_UI);
6✔
215
#else
216
        return -EOPNOTSUPP;
217
#endif
218
}
219

220
int efi_set_reboot_to_firmware(bool value) {
2✔
221
#if ENABLE_EFI
222
        int r;
2✔
223
        uint64_t b, b_new;
2✔
224

225
        r = get_os_indications(&b);
2✔
226
        if (r < 0)
2✔
227
                return r;
2✔
228

229
        b_new = UPDATE_FLAG(b, EFI_OS_INDICATIONS_BOOT_TO_FW_UI, value);
×
230

231
        /* Avoid writing to efi vars store if we can due to firmware bugs. */
232
        if (b != b_new)
×
233
                return efi_set_variable(EFI_GLOBAL_VARIABLE_STR("OsIndications"), &b_new, sizeof(uint64_t));
×
234

235
        return 0;
236
#else
237
        return -EOPNOTSUPP;
238
#endif
239
}
240

241
int efi_get_boot_option(
12✔
242
                uint16_t id,
243
                char **ret_title,
244
                sd_id128_t *ret_part_uuid,
245
                char **ret_path,
246
                bool *ret_active) {
247
#if ENABLE_EFI
248
        char variable[STRLEN(EFI_GLOBAL_VARIABLE_STR("Boot")) + 4 + 1];
12✔
249
        _cleanup_free_ uint8_t *buf = NULL;
24✔
250
        size_t l;
12✔
251
        struct boot_option *header;
12✔
252
        ssize_t title_size;
12✔
253
        _cleanup_free_ char *s = NULL, *p = NULL;
12✔
254
        sd_id128_t p_uuid = SD_ID128_NULL;
12✔
255
        int r;
12✔
256

257
        if (!is_efi_boot())
12✔
258
                return -EOPNOTSUPP;
259

260
        xsprintf(variable, EFI_GLOBAL_VARIABLE_STR("Boot%04X"), id);
12✔
261
        r = efi_get_variable(variable, NULL, (void **)&buf, &l);
12✔
262
        if (r < 0)
12✔
263
                return r;
264
        if (l < offsetof(struct boot_option, title))
12✔
265
                return -ENOENT;
266

267
        header = (struct boot_option *)buf;
12✔
268
        title_size = utf16_size(header->title, l - offsetof(struct boot_option, title));
12✔
269
        if (title_size < 0)
12✔
270
                return title_size;
×
271

272
        if (ret_title) {
12✔
273
                s = utf16_to_utf8(header->title, title_size);
12✔
274
                if (!s)
12✔
275
                        return -ENOMEM;
276
        }
277

278
        if (header->path_len > 0) {
12✔
279
                uint8_t *dbuf;
12✔
280
                size_t dnext, doff;
12✔
281

282
                doff = offsetof(struct boot_option, title) + title_size;
12✔
283
                dbuf = buf + doff;
12✔
284
                if (header->path_len > l - doff)
12✔
285
                        return -EINVAL;
286

287
                dnext = 0;
288
                while (dnext < header->path_len) {
36✔
289
                        struct device_path *dpath;
36✔
290

291
                        dpath = (struct device_path *)(dbuf + dnext);
36✔
292
                        if (dpath->length < 4)
36✔
293
                                break;
294

295
                        /* Type 0x7F – End of Hardware Device Path, Sub-Type 0xFF – End Entire Device Path */
296
                        if (dpath->type == END_DEVICE_PATH_TYPE && dpath->sub_type == END_ENTIRE_DEVICE_PATH_SUBTYPE)
36✔
297
                                break;
298

299
                        dnext += dpath->length;
24✔
300

301
                        /* Type 0x04 – Media Device Path */
302
                        if (dpath->type != MEDIA_DEVICE_PATH)
24✔
303
                                continue;
12✔
304

305
                        /* Sub-Type 1 – Hard Drive */
306
                        if (dpath->sub_type == MEDIA_HARDDRIVE_DP) {
12✔
307
                                /* 0x02 – GUID Partition Table */
308
                                if (dpath->drive.mbr_type != MBR_TYPE_EFI_PARTITION_TABLE_HEADER)
×
309
                                        continue;
×
310

311
                                /* 0x02 – GUID signature */
312
                                if (dpath->drive.signature_type != SIGNATURE_TYPE_GUID)
×
313
                                        continue;
×
314

315
                                if (ret_part_uuid)
×
316
                                        p_uuid = efi_guid_to_id128(dpath->drive.signature);
×
317
                                continue;
×
318
                        }
319

320
                        /* Sub-Type 4 – File Path */
321
                        if (dpath->sub_type == MEDIA_FILEPATH_DP && !p && ret_path) {
12✔
322
                                p = utf16_to_utf8(dpath->path, dpath->length-4);
×
323
                                if (!p)
×
324
                                        return  -ENOMEM;
325

326
                                efi_tilt_backslashes(p);
×
327
                                continue;
×
328
                        }
329
                }
330
        }
331

332
        if (ret_title)
12✔
333
                *ret_title = TAKE_PTR(s);
12✔
334
        if (ret_part_uuid)
12✔
335
                *ret_part_uuid = p_uuid;
12✔
336
        if (ret_path)
12✔
337
                *ret_path = TAKE_PTR(p);
12✔
338
        if (ret_active)
12✔
339
                *ret_active = header->attr & LOAD_OPTION_ACTIVE;
12✔
340

341
        return 0;
342
#else
343
        return -EOPNOTSUPP;
344
#endif
345
}
346

347
int efi_add_boot_option(
×
348
                uint16_t id,
349
                const char *title,
350
                uint32_t part,
351
                uint64_t pstart,
352
                uint64_t psize,
353
                sd_id128_t part_uuid,
354
                const char *path) {
355
#if ENABLE_EFI
356
        size_t size, title_len, path_len;
×
357
        _cleanup_free_ char *buf = NULL;
×
358
        struct boot_option *option;
×
359
        struct device_path *devicep;
×
360
        char variable[STRLEN(EFI_GLOBAL_VARIABLE_STR("Boot")) + 4 + 1];
×
361

362
        if (!is_efi_boot())
×
363
                return -EOPNOTSUPP;
364

365
        title_len = (strlen(title)+1) * 2;
×
366
        path_len = (strlen(path)+1) * 2;
×
367

368
        buf = malloc0(offsetof(struct boot_option, title) + title_len +
×
369
                      sizeof(struct drive_path) +
370
                      sizeof(struct device_path) + path_len);
371
        if (!buf)
×
372
                return -ENOMEM;
373

374
        /* header */
375
        option = (struct boot_option *)buf;
×
376
        option->attr = LOAD_OPTION_ACTIVE;
×
377
        option->path_len = offsetof(struct device_path, drive) + sizeof(struct drive_path) +
×
378
                           offsetof(struct device_path, path) + path_len +
×
379
                           offsetof(struct device_path, path);
380
        to_utf16(option->title, title);
×
381
        size = offsetof(struct boot_option, title) + title_len;
×
382

383
        /* partition info */
384
        devicep = (struct device_path *)(buf + size);
×
385
        devicep->type = MEDIA_DEVICE_PATH;
×
386
        devicep->sub_type = MEDIA_HARDDRIVE_DP;
×
387
        devicep->length = offsetof(struct device_path, drive) + sizeof(struct drive_path);
×
388
        memcpy(&devicep->drive.part_nr, &part, sizeof(uint32_t));
×
389
        memcpy(&devicep->drive.part_start, &pstart, sizeof(uint64_t));
×
390
        memcpy(&devicep->drive.part_size, &psize, sizeof(uint64_t));
×
391
        efi_id128_to_guid(part_uuid, devicep->drive.signature);
×
392
        devicep->drive.mbr_type = MBR_TYPE_EFI_PARTITION_TABLE_HEADER;
×
393
        devicep->drive.signature_type = SIGNATURE_TYPE_GUID;
×
394
        size += devicep->length;
×
395

396
        /* path to loader */
397
        devicep = (struct device_path *)(buf + size);
×
398
        devicep->type = MEDIA_DEVICE_PATH;
×
399
        devicep->sub_type = MEDIA_FILEPATH_DP;
×
400
        devicep->length = offsetof(struct device_path, path) + path_len;
×
401
        to_utf16(devicep->path, path);
×
402
        tilt_slashes(devicep->path);
×
403
        size += devicep->length;
×
404

405
        /* end of path */
406
        devicep = (struct device_path *)(buf + size);
×
407
        devicep->type = END_DEVICE_PATH_TYPE;
×
408
        devicep->sub_type = END_ENTIRE_DEVICE_PATH_SUBTYPE;
×
409
        devicep->length = offsetof(struct device_path, path);
×
410
        size += devicep->length;
×
411

412
        xsprintf(variable, EFI_GLOBAL_VARIABLE_STR("Boot%04X"), id);
×
413
        return efi_set_variable(variable, buf, size);
×
414
#else
415
        return -EOPNOTSUPP;
416
#endif
417
}
418

419
int efi_remove_boot_option(uint16_t id) {
×
420
#if ENABLE_EFI
421
        char variable[STRLEN(EFI_GLOBAL_VARIABLE_STR("Boot")) + 4 + 1];
×
422

423
        if (!is_efi_boot())
×
424
                return -EOPNOTSUPP;
×
425

426
        xsprintf(variable, EFI_GLOBAL_VARIABLE_STR("Boot%04X"), id);
×
427
        return efi_set_variable(variable, NULL, 0);
×
428
#else
429
        return -EOPNOTSUPP;
430
#endif
431
}
432

433
int efi_get_boot_order(uint16_t **ret_order) {
6✔
434
#if ENABLE_EFI
435
        _cleanup_free_ void *buf = NULL;
6✔
436
        size_t l;
6✔
437
        int r;
6✔
438

439
        assert(ret_order);
6✔
440

441
        if (!is_efi_boot())
6✔
442
                return -EOPNOTSUPP;
443

444
        r = efi_get_variable(EFI_GLOBAL_VARIABLE_STR("BootOrder"), NULL, &buf, &l);
6✔
445
        if (r < 0)
6✔
446
                return r;
447

448
        if (l <= 0)
6✔
449
                return -ENOENT;
450

451
        if (l % sizeof(uint16_t) > 0 ||
6✔
452
            l / sizeof(uint16_t) > INT_MAX)
453
                return -EINVAL;
454

455
        *ret_order = TAKE_PTR(buf);
6✔
456
        return (int) (l / sizeof(uint16_t));
6✔
457
#else
458
        return -EOPNOTSUPP;
459
#endif
460
}
461

462
int efi_set_boot_order(const uint16_t *order, size_t n) {
×
463
#if ENABLE_EFI
464
        if (!is_efi_boot())
×
465
                return -EOPNOTSUPP;
466

467
        return efi_set_variable(EFI_GLOBAL_VARIABLE_STR("BootOrder"), order, n * sizeof(uint16_t));
×
468
#else
469
        return -EOPNOTSUPP;
470
#endif
471
}
472

473
int efi_get_boot_options(uint16_t **ret_options) {
6✔
474
#if ENABLE_EFI
475
        _cleanup_closedir_ DIR *dir = NULL;
6✔
476
        _cleanup_free_ uint16_t *list = NULL;
6✔
477
        int count = 0;
6✔
478

479
        assert(ret_options);
6✔
480

481
        if (!is_efi_boot())
6✔
482
                return -EOPNOTSUPP;
483

484
        dir = opendir(EFIVAR_PATH("."));
6✔
485
        if (!dir)
6✔
486
                return -errno;
×
487

488
        FOREACH_DIRENT(de, dir, return -errno) {
303✔
489
                int id;
285✔
490

491
                if (!startswith(de->d_name, "Boot"))
285✔
492
                        continue;
255✔
493

494
                if (strlen(de->d_name) != 45)
30✔
495
                        continue;
18✔
496

497
                if (!streq(de->d_name + 8, EFI_GLOBAL_VARIABLE_STR(""))) /* generate variable suffix using macro */
12✔
498
                        continue;
×
499

500
                id = boot_id_hex(de->d_name + 4);
12✔
501
                if (id < 0)
12✔
502
                        continue;
×
503

504
                if (!GREEDY_REALLOC(list, count + 1))
12✔
505
                        return -ENOMEM;
506

507
                list[count++] = id;
12✔
508
        }
509

510
        typesafe_qsort(list, count, cmp_uint16);
6✔
511

512
        *ret_options = TAKE_PTR(list);
6✔
513

514
        return count;
6✔
515
#else
516
        return -EOPNOTSUPP;
517
#endif
518
}
519

520
#if ENABLE_EFI
521
static int loader_has_tpm2(void) {
67✔
522
        _cleanup_free_ char *active_pcr_banks = NULL;
67✔
523
        uint32_t active_pcr_banks_value;
67✔
524
        int r;
67✔
525

526
        r = efi_get_variable_string(EFI_LOADER_VARIABLE_STR("LoaderTpm2ActivePcrBanks"), &active_pcr_banks);
67✔
527
        if (r < 0) {
67✔
528
                if (r != -ENOENT)
×
529
                        log_debug_errno(r, "Failed to read LoaderTpm2ActivePcrBanks variable: %m");
×
530
                return r;
×
531
        }
532

533
        r = safe_atou32_full(active_pcr_banks, 16, &active_pcr_banks_value);
67✔
534
        if (r < 0)
67✔
535
                return log_debug_errno(r, "Failed to parse LoaderTpm2ActivePcrBanks variable: %m");
×
536

537
        return active_pcr_banks_value != 0;
67✔
538
}
539
#endif
540

541
bool efi_has_tpm2(void) {
153✔
542
#if ENABLE_EFI
543
        static int cache = -1;
153✔
544
        int r;
153✔
545

546
        /* Returns whether the system has a TPM2 chip which is known to the EFI firmware. */
547

548
        if (cache >= 0)
153✔
549
                return cache;
41✔
550

551
        /* First, check if we are on an EFI boot at all. */
552
        if (!is_efi_boot())
112✔
553
                return (cache = false);
45✔
554

555
        /* Secondly, check if the loader told us, as that is the most accurate source of information
556
         * regarding the firmware's setup */
557
        r = loader_has_tpm2();
67✔
558
        if (r >= 0)
67✔
559
                return (cache = r);
67✔
560

561
        /* Then, check if the ACPI table "TPM2" exists, which is the TPM2 event log table, see:
562
         * https://trustedcomputinggroup.org/wp-content/uploads/TCG_ACPIGeneralSpecification_v1.20_r8.pdf
563
         * This table exists whenever the firmware knows ACPI and is hooked up to TPM2.
564
         * Note that in some cases, for example with EDK2 2025.2 with the default arm64 config, this ACPI
565
         * table is present even if TPM2 support is not enabled in the firmware. */
566
        if (access("/sys/firmware/acpi/tables/TPM2", F_OK) >= 0)
×
567
                return (cache = true);
×
568
        if (errno != ENOENT)
×
569
                log_debug_errno(errno, "Unable to test whether /sys/firmware/acpi/tables/TPM2 exists, assuming it doesn't: %m");
×
570

571
        /* As the last try, check if the EFI firmware provides the EFI_TCG2_FINAL_EVENTS_TABLE
572
         * stored in EFI configuration table, see:
573
         *
574
         * https://trustedcomputinggroup.org/wp-content/uploads/EFI-Protocol-Specification-rev13-160330final.pdf */
575
        if (access("/sys/kernel/security/tpm0/binary_bios_measurements", F_OK) >= 0) {
×
576
                _cleanup_free_ char *major = NULL;
×
577

578
                /* The EFI table might exist for TPM 1.2 as well, hence let's check explicitly which TPM version we are looking at here. */
579
                r = read_virtual_file("/sys/class/tpm/tpm0/tpm_version_major", SIZE_MAX, &major, /* ret_size= */ NULL);
×
580
                if (r >= 0)
×
581
                        return (cache = streq(strstrip(major), "2"));
×
582

583
                log_debug_errno(r, "Unable to read /sys/class/tpm/tpm0/tpm_version_major, assuming TPM does not qualify as TPM2: %m");
×
584

585
        } else if (errno != ENOENT)
×
586
                  log_debug_errno(errno, "Unable to test whether /sys/kernel/security/tpm0/binary_bios_measurements exists, assuming it doesn't: %m");
×
587

588
        return (cache = false);
×
589
#else
590
        return -EOPNOTSUPP;
591
#endif
592
}
593

594
sd_id128_t efi_guid_to_id128(const void *guid) {
960✔
595
        const EFI_GUID *uuid = ASSERT_PTR(guid); /* cast is safe, because struct efi_guid is packed */
960✔
596
        sd_id128_t id128;
960✔
597

598
        id128.bytes[0] = (uuid->Data1 >> 24) & 0xff;
960✔
599
        id128.bytes[1] = (uuid->Data1 >> 16) & 0xff;
960✔
600
        id128.bytes[2] = (uuid->Data1 >> 8) & 0xff;
960✔
601
        id128.bytes[3] = uuid->Data1 & 0xff;
960✔
602

603
        id128.bytes[4] = (uuid->Data2 >> 8) & 0xff;
960✔
604
        id128.bytes[5] = uuid->Data2 & 0xff;
960✔
605

606
        id128.bytes[6] = (uuid->Data3 >> 8) & 0xff;
960✔
607
        id128.bytes[7] = uuid->Data3 & 0xff;
960✔
608

609
        memcpy(&id128.bytes[8], uuid->Data4, sizeof(uuid->Data4));
960✔
610

611
        return id128;
960✔
612
}
613

614
void efi_id128_to_guid(sd_id128_t id, void *ret_guid) {
×
615
        assert(ret_guid);
×
616

617
        EFI_GUID uuid = {
×
618
                .Data1 = id.bytes[0] << 24 | id.bytes[1] << 16 | id.bytes[2] << 8 | id.bytes[3],
×
619
                .Data2 = id.bytes[4] << 8 | id.bytes[5],
×
620
                .Data3 = id.bytes[6] << 8 | id.bytes[7],
×
621
        };
622
        memcpy(uuid.Data4, id.bytes+8, sizeof(uuid.Data4));
×
623
        memcpy(ret_guid, &uuid, sizeof(uuid));
×
624
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc