Stack buffer overflow during obj/filter/filter_test execution
Hi, ASAN reports stack-buffer-overflow in ip6_getbit() function during obj/filter/filter_test execution. How to reproduce the issue without ASAN: apply the following patch: diff --git a/lib/ip.h b/lib/ip.h index bae05261..e76ded9c 100644 --- a/lib/ip.h +++ b/lib/ip.h @@ -13,6 +13,7 @@ #include "lib/string.h" #include "lib/bitops.h" #include "lib/unaligned.h" +#include <stdio.h> #define IP4_ALL_NODES ipa_build4(224, 0, 0, 1) @@ -331,7 +332,9 @@ static inline u32 ip4_getbits(ip4_addr a, uint pos, uint n) { return (_I(a) >> ((32 - n) - pos)) & ((1u << n) - 1); } static inline u32 ip6_getbit(ip6_addr a, uint pos) -{ return (a.addr[pos / 32] >> (31 - (pos % 32))) & 0x1; } +{ +fprintf(stderr,"pos=%u\n",pos); + return (a.addr[pos / 32] >> (31 - (pos % 32))) & 0x1; } static inline u32 ip6_getbits(ip6_addr a, uint pos, uint n) { return (a.addr[pos / 32] >> ((32 - n) - (pos % 32))) & ((1u << n) - 1); } Then run the commands: autoreconf ./configure make -j make check -j obj/filter/filter_test You will see the following lines: pos=127 pos=128 (stack overflow is here) pos=129 pos=130 pos>=128 is invalid due to a.addr is 4xu32, it's not not 5xu32
A similar problem was also found in another function ip4_getbit(): during filter_test execution pos is greater than 31: (pos=32,33,34) so _I(a) >> (31 - pos) becomes UB This issue has been found by UBSAN.
On Fri, Aug 22, 2025 at 09:31:04PM +0300, Sergey L wrote:
Hi,
ASAN reports stack-buffer-overflow in ip6_getbit() function during obj/filter/filter_test execution.
Hi Thanks, seems like an issue with prefix set formatting code. Worth fixing, but it seems harmless.
How to reproduce the issue without ASAN: apply the following patch: diff --git a/lib/ip.h b/lib/ip.h index bae05261..e76ded9c 100644 --- a/lib/ip.h +++ b/lib/ip.h @@ -13,6 +13,7 @@ #include "lib/string.h" #include "lib/bitops.h" #include "lib/unaligned.h" +#include <stdio.h>
#define IP4_ALL_NODES ipa_build4(224, 0, 0, 1) @@ -331,7 +332,9 @@ static inline u32 ip4_getbits(ip4_addr a, uint pos, uint n) { return (_I(a) >> ((32 - n) - pos)) & ((1u << n) - 1); }
static inline u32 ip6_getbit(ip6_addr a, uint pos) -{ return (a.addr[pos / 32] >> (31 - (pos % 32))) & 0x1; } +{ +fprintf(stderr,"pos=%u\n",pos); + return (a.addr[pos / 32] >> (31 - (pos % 32))) & 0x1; }
static inline u32 ip6_getbits(ip6_addr a, uint pos, uint n) { return (a.addr[pos / 32] >> ((32 - n) - (pos % 32))) & ((1u << n) - 1); }
Then run the commands: autoreconf ./configure make -j make check -j obj/filter/filter_test
You will see the following lines: pos=127 pos=128 (stack overflow is here) pos=129 pos=130
pos>=128 is invalid due to a.addr is 4xu32, it's not not 5xu32
-- Elen sila lumenn' omentielvo Ondrej 'Santiago' Zajicek (email: santiago@crfreenet.org) "To err is human -- to blame it on a computer is even more so."
participants (2)
-
Ondrej Zajicek -
Sergey L