diff --git a/tap.c b/tap.c index a47f9d3..7d9113a 100644 --- a/tap.c +++ b/tap.c @@ -1011,7 +1011,7 @@ void tap_handler_passt(struct ctx *c, uint32_t events, } while (n > (ssize_t)sizeof(uint32_t)) { - uint32_t l2len = ntohl(*(uint32_t *)p); + uint32_t l2len = ntohl_unaligned(p); if (l2len < sizeof(struct ethhdr) || l2len > ETH_MAX_MTU) { err("Bad frame size from guest, resetting connection"); diff --git a/util.h b/util.h index 6f44eab..b7541ce 100644 --- a/util.h +++ b/util.h @@ -10,8 +10,10 @@ #include #include #include +#include #include #include +#include #include "log.h" @@ -116,6 +118,20 @@ #define htonl_constant(x) (__bswap_constant_32(x)) #endif +/** + * ntohl_unaligned() - Read 32-bit BE value from a possibly unaligned address + * @p: Pointer to the BE value in memory + * + * Returns: Host-order value of 32-bit BE quantity at @p + */ +static inline uint32_t ntohl_unaligned(const void *p) +{ + uint32_t val; + + memcpy(&val, p, sizeof(val)); + return ntohl(val); +} + #define NS_FN_STACK_SIZE (RLIMIT_STACK_VAL * 1024 / 8) int do_clone(int (*fn)(void *), char *stack_area, size_t stack_size, int flags, void *arg);