From 204305a88fb32cffaf1349253a2b052186ca8d39 Mon Sep 17 00:00:00 2001 From: Yves Rutschle Date: Sun, 25 May 2025 11:27:26 +0200 Subject: [PATCH] fix unaligned read in OpenVPN UDP probe --- Makefile.in | 2 +- probe.c | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Makefile.in b/Makefile.in index 96f9656..adc3470 100644 --- a/Makefile.in +++ b/Makefile.in @@ -22,7 +22,7 @@ MAN=sslh.8.gz # man page name # itself ifneq ($(strip $(ENABLE_SANITIZER)),) - CFLAGS_SAN=-fsanitize=address -fsanitize=leak -fsanitize=undefined + CFLAGS_SAN=-fsanitize=address -fsanitize=leak -fsanitize=undefined -fsanitize=alignment endif ifneq ($(strip $(COV_TEST)),) diff --git a/probe.c b/probe.c index 61f2cb7..37f9bb6 100644 --- a/probe.c +++ b/probe.c @@ -147,6 +147,7 @@ static int is_ssh_protocol(const char *p, ssize_t len, struct sslhcfg_protocols_ #define OVPN_OPCODE_MASK 0xF8 #define OVPN_CONTROL_HARD_RESET_CLIENT_V1 (0x01 << 3) #define OVPN_CONTROL_HARD_RESET_CLIENT_V2 (0x07 << 3) +#define OVPN_CONTROL_HARD_RESET_CLIENT_V3 (0x0A << 3) #define OVPN_HMAC_128 16 #define OVPN_HMAC_160 20 #define OVPN_HARD_RESET_PACKET_ID_OFFSET(hmac_size) (9 + hmac_size) @@ -165,8 +166,12 @@ static int is_openvpn_protocol (const char*p,ssize_t len, struct sslhcfg_protoco if (len < 1) return PROBE_NEXT; + printf("opcode: %d\n", (p[0] & OVPN_OPCODE_MASK) >> 3); + if ((p[0] & OVPN_OPCODE_MASK) != OVPN_CONTROL_HARD_RESET_CLIENT_V1 && - (p[0] & OVPN_OPCODE_MASK) != OVPN_CONTROL_HARD_RESET_CLIENT_V2) + (p[0] & OVPN_OPCODE_MASK) != OVPN_CONTROL_HARD_RESET_CLIENT_V2 && + (p[0] & OVPN_OPCODE_MASK) != OVPN_CONTROL_HARD_RESET_CLIENT_V3 + ) return PROBE_NEXT; /* The detection pattern above may not be reliable enough. @@ -177,12 +182,18 @@ static int is_openvpn_protocol (const char*p,ssize_t len, struct sslhcfg_protoco if (len <= OVPN_HARD_RESET_PACKET_ID_OFFSET(OVPN_HMAC_128) + sizeof(uint32_t)) return PROBE_NEXT; - if (ntohl(*(uint32_t*)(p + OVPN_HARD_RESET_PACKET_ID_OFFSET(OVPN_HMAC_128))) <= 5u) + uint32_t i; + /* OVPN_HMAC_128 is unaligned, which requires special care e.g. on ARM */ + memcpy(&i, (p + OVPN_HARD_RESET_PACKET_ID_OFFSET(OVPN_HMAC_128)), sizeof(i)); + i = ntohl(i); + if (i <= 5u) return PROBE_MATCH; if (len <= OVPN_HARD_RESET_PACKET_ID_OFFSET(OVPN_HMAC_160) + sizeof(uint32_t)) return PROBE_NEXT; + memcpy(&i, (p + OVPN_HARD_RESET_PACKET_ID_OFFSET(OVPN_HMAC_160)), sizeof(i)); + i = ntohl(i); if (ntohl(*(uint32_t*)(p + OVPN_HARD_RESET_PACKET_ID_OFFSET(OVPN_HMAC_160))) <= 5u) return PROBE_MATCH;