]> www.infradead.org Git - users/sagi/libnvme.git/commitdiff
nbft: Avoid unaligned pointer dereferences
authorCaleb Sander <csander@purestorage.com>
Sat, 14 Oct 2023 04:35:43 +0000 (22:35 -0600)
committerDaniel Wagner <wagi@monom.org>
Thu, 2 Nov 2023 13:31:26 +0000 (14:31 +0100)
Avoid casting byte-aligned pointers to pointers with higher alignment.
Loading or storing values with higher alignment is undefined behavior,
since some processors don't allow unaligned memory accesses
and compilers may assume pointers of different types don't alias.
Perform an explicit memcpy() in two places, which an optimizing compiler
can easily replace with a single load/store on supported architectures.

While we're touching this code, also use IN6_IS_ADDR_V4MAPPED()
instead of hand-rolling it.

Signed-off-by: Caleb Sander <csander@purestorage.com>
src/nvme/nbft.c

index a1e17cd8ecc8b758f9f3f3fa17c308f413cc5956..300703b66414e568d11f5b9e4cfc171a21c3ded5 100644 (file)
@@ -33,17 +33,15 @@ static __u8 csum(const __u8 *buffer, ssize_t length)
 
 static void format_ip_addr(char *buf, size_t buflen, __u8 *addr)
 {
-       struct in6_addr *addr_ipv6;
+       struct in6_addr addr_ipv6;
 
-       addr_ipv6 = (struct in6_addr *)addr;
-       if (addr_ipv6->s6_addr32[0] == 0 &&
-           addr_ipv6->s6_addr32[1] == 0 &&
-           ntohl(addr_ipv6->s6_addr32[2]) == 0xffff)
+       memcpy(&addr_ipv6, addr, sizeof(addr_ipv6));
+       if (IN6_IS_ADDR_V4MAPPED(&addr_ipv6))
                /* ipv4 */
-               inet_ntop(AF_INET, &(addr_ipv6->s6_addr32[3]), buf, buflen);
+               inet_ntop(AF_INET, &addr_ipv6.s6_addr32[3], buf, buflen);
        else
                /* ipv6 */
-               inet_ntop(AF_INET6, addr_ipv6, buf, buflen);
+               inet_ntop(AF_INET6, &addr_ipv6, buf, buflen);
 }
 
 static bool in_heap(struct nbft_header *header, struct nbft_heap_obj obj)