From: Greg Kroah-Hartman Date: Thu, 9 Apr 2026 11:06:42 +0000 (+0200) Subject: BUG/MINOR: spoe: fix pointer arithmetic overflow in spoe_decode_buffer() X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bd03f05007d867aa8e86b6c2cd376d525729cacf;p=thirdparty%2Fhaproxy.git BUG/MINOR: spoe: fix pointer arithmetic overflow in spoe_decode_buffer() decode_varint() has no iteration cap and accepts varints decoding to any uint64_t value. When sz is large enough that p + sz wraps modulo 2^64, the check "p + sz > end" passes, *buf is set to the wrapped pointer, and the caller's parsing loop continues from an arbitrary relative offset before the demux buffer. A malicious SPOE agent sending an AGENT_HELLO frame with a key-name length varint of 0xfffffffffffff000 causes spop_conn_handle_hello() to dereference memory ~64KB before the dbuf allocation, resulting in SIGSEGV (DoS) or, if the read lands on live heap data, parser confusion. The relative offset is fully attacker-controlled and ASLR-independent. Compare against the remaining length instead of computing p + sz. Since p <= end is guaranteed after a successful decode_varint(), end - p is non-negative. This patch must be backport to all stable versions. --- diff --git a/include/haproxy/spoe.h b/include/haproxy/spoe.h index 585b8bff9..eeae37181 100644 --- a/include/haproxy/spoe.h +++ b/include/haproxy/spoe.h @@ -76,7 +76,7 @@ static inline int spoe_decode_buffer(char **buf, char *end, char **str, uint64_t *len = 0; ret = decode_varint(&p, end, &sz); - if (ret == -1 || p + sz > end) + if (ret == -1 || sz > (uint64_t)(end - p)) return -1; *str = p;