From cd8c98d7a75435e5b3eebc927560788acef27f60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 27 Jan 2019 09:35:36 +0100 Subject: [PATCH 1/9] shared/dissect-image: make sure that we don't truncate device name gcc-9 complains that the string may be truncated when written into the output structure. This shouldn't happen, but if it did, in principle we could remove a different structure (with a matching name prefix). Let's just refuse the operation if the name doesn't fit. --- src/shared/dissect-image.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 3a46faf769e..d3404870254 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -1178,7 +1178,6 @@ int dissected_image_decrypt_interactively( #if HAVE_LIBCRYPTSETUP static int deferred_remove(DecryptedPartition *p) { - struct dm_ioctl dm = { .version = { DM_VERSION_MAJOR, @@ -1199,6 +1198,9 @@ static int deferred_remove(DecryptedPartition *p) { if (fd < 0) return -errno; + if (strlen(p->name) > sizeof(dm.name)) + return -ENAMETOOLONG; + strncpy(dm.name, p->name, sizeof(dm.name)); if (ioctl(fd, DM_DEV_REMOVE, &dm)) From 00e1adf8b1477e8770a49bc2b0ebc2f611f57906 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 27 Jan 2019 09:37:26 +0100 Subject: [PATCH 2/9] journal: avoid buffer overread when locale name is too long We could potentially create an unterminated string and then call normal string operations on it. Let's be more careful: first remove the suffix we ignore anyway, then find if the string is of acceptable length, and possibly ignore it if it is too long. The code rejects lengths above 31 bytes. Language names that are actually used are much shorter, so this doesn't matter much. --- src/journal/catalog.c | 44 +++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/src/journal/catalog.c b/src/journal/catalog.c index 3556a101bf2..4062f12c2df 100644 --- a/src/journal/catalog.c +++ b/src/journal/catalog.c @@ -46,7 +46,8 @@ typedef struct CatalogHeader { typedef struct CatalogItem { sd_id128_t id; - char language[32]; + char language[32]; /* One byte is used for termination, so the maximum allowed + * length of the string is actually 31 bytes. */ le64_t offset; } CatalogItem; @@ -556,25 +557,44 @@ static const char *find_id(void *p, sd_id128_t id) { const char *loc; loc = setlocale(LC_MESSAGES, NULL); - if (loc && loc[0] && !streq(loc, "C") && !streq(loc, "POSIX")) { - strncpy(key.language, loc, sizeof(key.language)); - key.language[strcspn(key.language, ".@")] = 0; + if (!isempty(loc) && !STR_IN_SET(loc, "C", "POSIX")) { + size_t len; - f = bsearch(&key, (const uint8_t*) p + le64toh(h->header_size), le64toh(h->n_items), le64toh(h->catalog_item_size), (comparison_fn_t) catalog_compare_func); - if (!f) { - char *e; + len = strcspn(loc, ".@"); + if (len > sizeof(key.language) - 1) + log_debug("LC_MESSAGES value too long, ignoring: \"%.*s\"", (int) len, loc); + else { + strncpy(key.language, loc, len); + key.language[len] = '\0'; - e = strchr(key.language, '_'); - if (e) { - *e = 0; - f = bsearch(&key, (const uint8_t*) p + le64toh(h->header_size), le64toh(h->n_items), le64toh(h->catalog_item_size), (comparison_fn_t) catalog_compare_func); + f = bsearch(&key, + (const uint8_t*) p + le64toh(h->header_size), + le64toh(h->n_items), + le64toh(h->catalog_item_size), + (comparison_fn_t) catalog_compare_func); + if (!f) { + char *e; + + e = strchr(key.language, '_'); + if (e) { + *e = 0; + f = bsearch(&key, + (const uint8_t*) p + le64toh(h->header_size), + le64toh(h->n_items), + le64toh(h->catalog_item_size), + (comparison_fn_t) catalog_compare_func); + } } } } if (!f) { zero(key.language); - f = bsearch(&key, (const uint8_t*) p + le64toh(h->header_size), le64toh(h->n_items), le64toh(h->catalog_item_size), (comparison_fn_t) catalog_compare_func); + f = bsearch(&key, + (const uint8_t*) p + le64toh(h->header_size), + le64toh(h->n_items), + le64toh(h->catalog_item_size), + (comparison_fn_t) catalog_compare_func); } if (!f) From e27b9aba30381331905619d62af276bf5f967b8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 27 Jan 2019 17:09:21 +0100 Subject: [PATCH 3/9] libsystemd-network: remove _packed_ attribute to appease the compiler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gcc-9 warns whenever the elements of a structure defined with _packed_ are used: ../src/network/networkd-dhcp6.c: In function ‘dhcp6_pd_prefix_assign’: ../src/network/networkd-dhcp6.c:92:53: warning: taking address of packed member of ‘struct ’ may result in an unaligned pointer value [-Waddress-of-packed-member] 92 | r = manager_dhcp6_prefix_add(link->manager, &p->opt.in6_addr, link); | ^~~~~~~~~~~~~~~~ And the compiler is right, because in principle the alignment could be wrong. In this particular case it is not, because the structure is carefully defined not to have holes. Let's remove _packed_ and use compile-time asserts to verify that the offsets are not changed. --- src/libsystemd-network/radv-internal.h | 35 ++++++++++++++++++-------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/src/libsystemd-network/radv-internal.h b/src/libsystemd-network/radv-internal.h index cd443523072..66f49ed44ec 100644 --- a/src/libsystemd-network/radv-internal.h +++ b/src/libsystemd-network/radv-internal.h @@ -63,19 +63,34 @@ struct sd_radv { struct sd_radv_opt_dns *dnssl; }; +#define radv_prefix_opt__contents { \ + uint8_t type; \ + uint8_t length; \ + uint8_t prefixlen; \ + uint8_t flags; \ + be32_t valid_lifetime; \ + be32_t preferred_lifetime; \ + uint32_t reserved; \ + struct in6_addr in6_addr; \ +} + +struct radv_prefix_opt radv_prefix_opt__contents; + +/* We need the opt substructure to be packed, because we use it in send(). But + * if we use _packed_, this means that the structure cannot be used directly in + * normal code in general, because the fields might not be properly aligned. + * But in this particular case, the structure is defined in a way that gives + * proper alignment, even without the explicit _packed_ attribute. To appease + * the compiler we use the "unpacked" structure, but we also verify that + * structure contains no holes, so offsets are the same when _packed_ is used. + */ +struct radv_prefix_opt__packed radv_prefix_opt__contents _packed_; +assert_cc(sizeof(struct radv_prefix_opt) == sizeof(struct radv_prefix_opt__packed)); + struct sd_radv_prefix { unsigned n_ref; - struct { - uint8_t type; - uint8_t length; - uint8_t prefixlen; - uint8_t flags; - be32_t valid_lifetime; - be32_t preferred_lifetime; - uint32_t reserved; - struct in6_addr in6_addr; - } _packed_ opt; + struct radv_prefix_opt opt; LIST_FIELDS(struct sd_radv_prefix, prefix); From 6b68c26824affd2c22556ab6e8ff4df58785d7ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 27 Jan 2019 17:13:42 +0100 Subject: [PATCH 4/9] test-util: drop _packed_ attribute MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gcc-9 warns: ../src/test/test-util.c:147:19: note: in expansion of macro ‘container_of’ 147 | assert_se(container_of(&myval.v1, struct mytype, v1) == &myval); | ^~~~~~~~~~~~ I don't think packing matters here for the test of container_of(), so let's just remove it. --- src/test/test-util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/test-util.c b/src/test/test-util.c index 3c1b5f9b413..40c1f4a3aa2 100644 --- a/src/test/test-util.c +++ b/src/test/test-util.c @@ -139,11 +139,11 @@ static void test_container_of(void) { uint64_t v1; uint8_t pad2[2]; uint32_t v2; - } _packed_ myval = { }; + } myval = { }; log_info("/* %s */", __func__); - assert_cc(sizeof(myval) == 17); + assert_cc(sizeof(myval) >= 17); assert_se(container_of(&myval.v1, struct mytype, v1) == &myval); assert_se(container_of(&myval.v2, struct mytype, v2) == &myval); assert_se(container_of(&container_of(&myval.v2, From 62353f69cc31cc6ce706b6ddcc6f77a71f29bf42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 27 Jan 2019 18:04:22 +0100 Subject: [PATCH 5/9] journal: drop _packed_ attribute in a few places The justification is the safe as for the grandparent commit. --- TODO | 2 + src/journal/journal-def.h | 116 +++++++++++++++++++++----------------- 2 files changed, 66 insertions(+), 52 deletions(-) diff --git a/TODO b/TODO index 77a84472336..462db57a3a5 100644 --- a/TODO +++ b/TODO @@ -1114,3 +1114,5 @@ Regularly: * use secure_getenv() instead of getenv() where appropriate * link up selected blog stories from man pages and unit files Documentation= fields +String is not UTF-8 clean, ignoring assignment + timedatex.service: Consumed 26ms CPU time. diff --git a/src/journal/journal-def.h b/src/journal/journal-def.h index e48260206f8..d68ce3894b3 100644 --- a/src/journal/journal-def.h +++ b/src/journal/journal-def.h @@ -59,16 +59,20 @@ struct ObjectHeader { uint8_t payload[]; } _packed_; -struct DataObject { - ObjectHeader object; - le64_t hash; - le64_t next_hash_offset; - le64_t next_field_offset; - le64_t entry_offset; /* the first array entry we store inline */ - le64_t entry_array_offset; - le64_t n_entries; - uint8_t payload[]; -} _packed_; +#define DataObject__contents { \ + ObjectHeader object; \ + le64_t hash; \ + le64_t next_hash_offset; \ + le64_t next_field_offset; \ + le64_t entry_offset; /* the first array entry we store inline */ \ + le64_t entry_array_offset; \ + le64_t n_entries; \ + uint8_t payload[]; \ + } + +struct DataObject DataObject__contents; +struct DataObject__packed DataObject__contents _packed_; +assert_cc(sizeof(struct DataObject) == sizeof(struct DataObject__packed)); struct FieldObject { ObjectHeader object; @@ -83,15 +87,20 @@ struct EntryItem { le64_t hash; } _packed_; -struct EntryObject { - ObjectHeader object; - le64_t seqnum; - le64_t realtime; - le64_t monotonic; - sd_id128_t boot_id; - le64_t xor_hash; - EntryItem items[]; -} _packed_; +#define EntryObject__contents { \ + ObjectHeader object; \ + le64_t seqnum; \ + le64_t realtime; \ + le64_t monotonic; \ + sd_id128_t boot_id; \ + le64_t xor_hash; \ + EntryItem items[]; \ + } + +struct EntryObject EntryObject__contents; +struct EntryObject__packed EntryObject__contents _packed_; +assert_cc(sizeof(struct EntryObject) == sizeof(struct EntryObject__packed)); + struct HashItem { le64_t head_hash_offset; @@ -166,40 +175,43 @@ enum { #define HEADER_SIGNATURE ((char[]) { 'L', 'P', 'K', 'S', 'H', 'H', 'R', 'H' }) -struct Header { - uint8_t signature[8]; /* "LPKSHHRH" */ - le32_t compatible_flags; - le32_t incompatible_flags; - uint8_t state; - uint8_t reserved[7]; - sd_id128_t file_id; - sd_id128_t machine_id; - sd_id128_t boot_id; /* last writer */ - sd_id128_t seqnum_id; - le64_t header_size; - le64_t arena_size; - le64_t data_hash_table_offset; - le64_t data_hash_table_size; - le64_t field_hash_table_offset; - le64_t field_hash_table_size; - le64_t tail_object_offset; - le64_t n_objects; - le64_t n_entries; - le64_t tail_entry_seqnum; - le64_t head_entry_seqnum; - le64_t entry_array_offset; - le64_t head_entry_realtime; - le64_t tail_entry_realtime; - le64_t tail_entry_monotonic; - /* Added in 187 */ - le64_t n_data; - le64_t n_fields; - /* Added in 189 */ - le64_t n_tags; - le64_t n_entry_arrays; +#define struct_Header__contents { \ + uint8_t signature[8]; /* "LPKSHHRH" */ \ + le32_t compatible_flags; \ + le32_t incompatible_flags; \ + uint8_t state; \ + uint8_t reserved[7]; \ + sd_id128_t file_id; \ + sd_id128_t machine_id; \ + sd_id128_t boot_id; /* last writer */ \ + sd_id128_t seqnum_id; \ + le64_t header_size; \ + le64_t arena_size; \ + le64_t data_hash_table_offset; \ + le64_t data_hash_table_size; \ + le64_t field_hash_table_offset; \ + le64_t field_hash_table_size; \ + le64_t tail_object_offset; \ + le64_t n_objects; \ + le64_t n_entries; \ + le64_t tail_entry_seqnum; \ + le64_t head_entry_seqnum; \ + le64_t entry_array_offset; \ + le64_t head_entry_realtime; \ + le64_t tail_entry_realtime; \ + le64_t tail_entry_monotonic; \ + /* Added in 187 */ \ + le64_t n_data; \ + le64_t n_fields; \ + /* Added in 189 */ \ + le64_t n_tags; \ + le64_t n_entry_arrays; \ + } - /* Size: 240 */ -} _packed_; +struct Header struct_Header__contents; +struct Header__packed struct_Header__contents _packed_; +assert_cc(sizeof(struct Header) == sizeof(struct Header__packed)); +assert_cc(sizeof(struct Header) == 240); #define FSS_HEADER_SIGNATURE ((char[]) { 'K', 'S', 'H', 'H', 'R', 'H', 'L', 'P' }) From c92ab239a05392d0e899fa30b848644050e30b73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 27 Jan 2019 18:43:41 +0100 Subject: [PATCH 6/9] test-resolve: increase timeout to 120s The test queries some domain names. If the DNS servers are unreachable, e.g. in a rawhide container I get the total runtime of 24.5s usually, but sometimes slightly longer, enough to reach the default timeout of 30s. --- src/test/meson.build | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/meson.build b/src/test/meson.build index d9d87e02c56..08026ea8c49 100644 --- a/src/test/meson.build +++ b/src/test/meson.build @@ -929,7 +929,8 @@ tests += [ [['src/libsystemd/sd-resolve/test-resolve.c'], [], - [threads]], + [threads], + '', 'timeout=120'], [['src/libsystemd/sd-login/test-login.c'], [], From f7cb1c7900951c1c01b2cddb4462c35af2933114 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 5 Feb 2019 17:05:56 +0100 Subject: [PATCH 7/9] efivars: make sure that _packed_ structure members are actually aligned as expected When looking for the terminating double-NUL, don't just read the memory until the terminator is found, but use the information we got about the buffer size. The length parameter passed to utf16_to_utf8() would include the terminator, so the converted string would end up with two terminators (the original one converted to "utf8", still 0, and then the one that was always added anyway). Instead let's pass just the length of the actual data to utf16_to_utf8(). --- src/shared/efivars.c | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/src/shared/efivars.c b/src/shared/efivars.c index 23d38fb484b..0c7adb30fb9 100644 --- a/src/shared/efivars.c +++ b/src/shared/efivars.c @@ -40,11 +40,17 @@ #define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff #define EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001 -struct boot_option { - uint32_t attr; - uint16_t path_len; - uint16_t title[]; -} _packed_; +#define boot_option__contents { \ + uint32_t attr; \ + uint16_t path_len; \ + uint16_t title[]; \ + } + +struct boot_option boot_option__contents; +struct boot_option__packed boot_option__contents _packed_; +assert_cc(offsetof(struct boot_option, title) == offsetof(struct boot_option__packed, title)); +/* sizeof(struct boot_option) != sizeof(struct boot_option__packed), so + * the *size* of the structure should not be used anywhere below. */ struct drive_path { uint32_t part_nr; @@ -354,13 +360,21 @@ int efi_set_variable_string(sd_id128_t vendor, const char *name, const char *v) return efi_set_variable(vendor, name, u16, (char16_strlen(u16) + 1) * sizeof(char16_t)); } -static size_t utf16_size(const uint16_t *s) { +static ssize_t utf16_size(const uint16_t *s, size_t buf_len_bytes) { size_t l = 0; - while (s[l] > 0) - l++; + /* Returns the size of the string in bytes without the terminating two zero bytes */ - return (l+1) * sizeof(uint16_t); + if (buf_len_bytes % sizeof(uint16_t) != 0) + return -EINVAL; + + while (l < buf_len_bytes / sizeof(uint16_t)) { + if (s[l] == 0) + return (l + 1) * sizeof(uint16_t); + l++; + } + + return -EINVAL; /* The terminator was not found */ } static void efi_guid_to_id128(const void *guid, sd_id128_t *id128) { @@ -394,7 +408,7 @@ int efi_get_boot_option( _cleanup_free_ uint8_t *buf = NULL; size_t l; struct boot_option *header; - size_t title_size; + ssize_t title_size; _cleanup_free_ char *s = NULL, *p = NULL; sd_id128_t p_uuid = SD_ID128_NULL; int r; @@ -406,13 +420,13 @@ int efi_get_boot_option( r = efi_get_variable(EFI_VENDOR_GLOBAL, boot_id, NULL, (void **)&buf, &l); if (r < 0) return r; - if (l < sizeof(struct boot_option)) + if (l < offsetof(struct boot_option, title)) return -ENOENT; header = (struct boot_option *)buf; - title_size = utf16_size(header->title); - if (title_size > l - offsetof(struct boot_option, title)) - return -EINVAL; + title_size = utf16_size(header->title, l - offsetof(struct boot_option, title)); + if (title_size < 0) + return title_size; if (title) { s = utf16_to_utf8(header->title, title_size); @@ -541,7 +555,7 @@ int efi_add_boot_option( title_len = (strlen(title)+1) * 2; path_len = (strlen(path)+1) * 2; - buf = malloc0(sizeof(struct boot_option) + title_len + + buf = malloc0(offsetof(struct boot_option, title) + title_len + sizeof(struct drive_path) + sizeof(struct device_path) + path_len); if (!buf) From 3c7dddaccf2dba72b7718eaab4247cac542b4417 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 5 Feb 2019 17:35:39 +0100 Subject: [PATCH 8/9] efivars: remove direct access to unaligned structure members Most of the accesses *were* aligned. The only one that definetely wasn't was to drive_path->part_start and drive_path->part_size, because those both expect 8 byte alignment, and are at offsets 4 and 12 in the packed structure. Because of the way that device_path structure is defined and used, we expect that device_path.length is always two-byte aligned. This adds asserts in various places to ensure the proper alignment, and uses memcpy in other places where the alignment might be off. --- src/shared/efivars.c | 90 +++++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 43 deletions(-) diff --git a/src/shared/efivars.c b/src/shared/efivars.c index 0c7adb30fb9..26f905bfaa6 100644 --- a/src/shared/efivars.c +++ b/src/shared/efivars.c @@ -61,15 +61,19 @@ struct drive_path { uint8_t signature_type; } _packed_; -struct device_path { - uint8_t type; - uint8_t sub_type; - uint16_t length; - union { - uint16_t path[0]; - struct drive_path drive; - }; -} _packed_; +#define device_path__contents { \ + uint8_t type; \ + uint8_t sub_type; \ + uint16_t length; \ + union { \ + uint16_t path[0]; \ + struct drive_path drive; \ + }; \ + } + +struct device_path device_path__contents; +struct device_path__packed device_path__contents _packed_; +assert_cc(sizeof(struct device_path) == sizeof(struct device_path__packed)); bool is_efi_boot(void) { if (detect_container() > 0) @@ -377,23 +381,29 @@ static ssize_t utf16_size(const uint16_t *s, size_t buf_len_bytes) { return -EINVAL; /* The terminator was not found */ } -static void efi_guid_to_id128(const void *guid, sd_id128_t *id128) { - struct uuid { - uint32_t u1; - uint16_t u2; - uint16_t u3; - uint8_t u4[8]; - } _packed_; - const struct uuid *uuid = guid; +struct guid { + uint32_t u1; + uint16_t u2; + uint16_t u3; + uint8_t u4[8]; +} _packed_; - id128->bytes[0] = (uuid->u1 >> 24) & 0xff; - id128->bytes[1] = (uuid->u1 >> 16) & 0xff; - id128->bytes[2] = (uuid->u1 >> 8) & 0xff; - id128->bytes[3] = (uuid->u1) & 0xff; - id128->bytes[4] = (uuid->u2 >> 8) & 0xff; - id128->bytes[5] = (uuid->u2) & 0xff; - id128->bytes[6] = (uuid->u3 >> 8) & 0xff; - id128->bytes[7] = (uuid->u3) & 0xff; +static void efi_guid_to_id128(const void *guid, sd_id128_t *id128) { + uint32_t u1; + uint16_t u2, u3; + const struct guid *uuid = guid; + + memcpy(&u1, &uuid->u1, sizeof(uint32_t)); + id128->bytes[0] = (u1 >> 24) & 0xff; + id128->bytes[1] = (u1 >> 16) & 0xff; + id128->bytes[2] = (u1 >> 8) & 0xff; + id128->bytes[3] = u1 & 0xff; + memcpy(&u2, &uuid->u2, sizeof(uint16_t)); + id128->bytes[4] = (u2 >> 8) & 0xff; + id128->bytes[5] = u2 & 0xff; + memcpy(&u3, &uuid->u3, sizeof(uint16_t)); + id128->bytes[6] = (u3 >> 8) & 0xff; + id128->bytes[7] = u3 & 0xff; memcpy(&id128->bytes[8], uuid->u4, sizeof(uuid->u4)); } @@ -508,20 +518,14 @@ static void to_utf16(uint16_t *dest, const char *src) { dest[i] = '\0'; } -struct guid { - uint32_t u1; - uint16_t u2; - uint16_t u3; - uint8_t u4[8]; -} _packed_; - static void id128_to_efi_guid(sd_id128_t id, void *guid) { - struct guid *uuid = guid; - - uuid->u1 = id.bytes[0] << 24 | id.bytes[1] << 16 | id.bytes[2] << 8 | id.bytes[3]; - uuid->u2 = id.bytes[4] << 8 | id.bytes[5]; - uuid->u3 = id.bytes[6] << 8 | id.bytes[7]; - memcpy(uuid->u4, id.bytes+8, sizeof(uuid->u4)); + struct guid uuid = { + .u1 = id.bytes[0] << 24 | id.bytes[1] << 16 | id.bytes[2] << 8 | id.bytes[3], + .u2 = id.bytes[4] << 8 | id.bytes[5], + .u3 = id.bytes[6] << 8 | id.bytes[7], + }; + memcpy(uuid.u4, id.bytes+8, sizeof(uuid.u4)); + memcpy(guid, &uuid, sizeof(uuid)); } static uint16_t *tilt_slashes(uint16_t *s) { @@ -575,12 +579,12 @@ int efi_add_boot_option( devicep->type = MEDIA_DEVICE_PATH; devicep->sub_type = MEDIA_HARDDRIVE_DP; devicep->length = offsetof(struct device_path, drive) + sizeof(struct drive_path); - devicep->drive.part_nr = part; - devicep->drive.part_start = pstart; - devicep->drive.part_size = psize; - devicep->drive.signature_type = SIGNATURE_TYPE_GUID; - devicep->drive.mbr_type = MBR_TYPE_EFI_PARTITION_TABLE_HEADER; + memcpy(&devicep->drive.part_nr, &part, sizeof(uint32_t)); + memcpy(&devicep->drive.part_start, &pstart, sizeof(uint64_t)); + memcpy(&devicep->drive.part_size, &psize, sizeof(uint64_t)); id128_to_efi_guid(part_uuid, devicep->drive.signature); + devicep->drive.mbr_type = MBR_TYPE_EFI_PARTITION_TABLE_HEADER; + devicep->drive.signature_type = SIGNATURE_TYPE_GUID; size += devicep->length; /* path to loader */ From 23cfbcc35eda8150c653b549ae48c3ead0888279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 5 Feb 2019 18:56:41 +0100 Subject: [PATCH 9/9] test-sizeof: print the alignments too --- src/test/test-sizeof.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/test/test-sizeof.c b/src/test/test-sizeof.c index 7a1e496ed2f..35b087653ef 100644 --- a/src/test/test-sizeof.c +++ b/src/test/test-sizeof.c @@ -13,11 +13,12 @@ #pragma GCC diagnostic ignored "-Wtype-limits" -#define info(t) \ - printf("%s → %zu bits%s\n", STRINGIFY(t), \ - sizeof(t)*CHAR_BIT, \ - strstr(STRINGIFY(t), "signed") ? "" : \ - ((t)-1 < (t)0 ? ", signed" : ", unsigned")); +#define info(t) \ + printf("%s → %zu bits%s, %zu byte alignment\n", STRINGIFY(t), \ + sizeof(t)*CHAR_BIT, \ + strstr(STRINGIFY(t), "signed") ? "" : \ + (t)-1 < (t)0 ? ", signed" : ", unsigned", \ + __alignof__(t)) enum Enum { enum_value,