diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-02-06 12:53:34 +0100 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-02-14 06:43:45 +0100 |
commit | 0123b2dbacade0e05b708231b307ad510bd9fc44 (patch) | |
tree | c7ae41e48e6e5b29092e54b1d0e918243cebe2f0 | |
parent | sd-dhcp6-client: voidify client_reset() (diff) | |
download | systemd-0123b2dbacade0e05b708231b307ad510bd9fc44.tar.xz systemd-0123b2dbacade0e05b708231b307ad510bd9fc44.zip |
sd-dhcp6-client: fix possible unaligned read or write
-rw-r--r-- | src/libsystemd-network/dhcp6-option.c | 18 |
1 files changed, 6 insertions, 12 deletions
diff --git a/src/libsystemd-network/dhcp6-option.c b/src/libsystemd-network/dhcp6-option.c index cd67ab2c37..ac032f07fd 100644 --- a/src/libsystemd-network/dhcp6-option.c +++ b/src/libsystemd-network/dhcp6-option.c @@ -212,19 +212,15 @@ bool dhcp6_option_can_request(uint16_t option) { } static int option_append_hdr(uint8_t **buf, size_t *buflen, uint16_t optcode, size_t optlen) { - DHCP6Option *option; - assert_return(buf, -EINVAL); assert_return(*buf, -EINVAL); assert_return(buflen, -EINVAL); - option = (DHCP6Option*) *buf; - if (optlen > 0xffff || *buflen < optlen + offsetof(DHCP6Option, data)) return -ENOBUFS; - option->code = htobe16(optcode); - option->len = htobe16(optlen); + unaligned_write_be16(*buf + offsetof(DHCP6Option, code), optcode); + unaligned_write_be16(*buf + offsetof(DHCP6Option, len), optlen); *buf += offsetof(DHCP6Option, data); *buflen -= offsetof(DHCP6Option, data); @@ -511,7 +507,6 @@ int dhcp6_option_parse( size_t *ret_option_data_len, const uint8_t **ret_option_data) { - const DHCP6Option *option; size_t len; assert(buf); @@ -526,16 +521,15 @@ int dhcp6_option_parse( if (*offset >= buflen - offsetof(DHCP6Option, data)) return -EBADMSG; - option = (const DHCP6Option*) (buf + *offset); - len = be16toh(option->len); + len = unaligned_read_be16(buf + *offset + offsetof(DHCP6Option, len)); if (len > buflen - offsetof(DHCP6Option, data) - *offset) return -EBADMSG; - *offset += offsetof(DHCP6Option, data) + len; - *ret_option_code = be16toh(option->code); + *ret_option_code = unaligned_read_be16(buf + *offset + offsetof(DHCP6Option, code)); *ret_option_data_len = len; - *ret_option_data = option->data; + *ret_option_data = buf + *offset + offsetof(DHCP6Option, data); + *offset += offsetof(DHCP6Option, data) + len; return 0; } |