Hello,
We are Alexis Pinson and Lyes Bourennani, security researchers at FuzzingLabs. We found a bug while specifically fuzzing the BATMAN ADV protocol using Syzkaller. This was done with external network fuzzing that leverages TUN/TAP interfaces and a custom made grammar. We will shortly create a PR in Syzkaller to push this configuration.
This is the KASAN trace given by Syzkaller:
==================================================================
BUG: KASAN: use-after-free in batadv_iv_ogm_aggr_packet net/batman-adv/bat_iv_ogm.c:326 [inline]
BUG: KASAN: use-after-free in batadv_iv_ogm_send_to_if net/batman-adv/bat_iv_ogm.c:352 [inline]
BUG: KASAN: use-after-free in batadv_iv_ogm_emit net/batman-adv/bat_iv_ogm.c:419 [inline]
BUG: KASAN: use-after-free in batadv_iv_send_outstanding_bat_ogm_packet+0xa4a/0xb10 net/batman-adv/bat_iv_ogm.c:1700
Read of size 2 at addr ffff8880253bab26 by task kworker/u8:3/107378
CPU: 1 UID: 0 PID: 107378 Comm: kworker/u8:3 Not tainted 7.0.0 #1 PREEMPT(lazy)
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Workqueue: bat_events batadv_iv_send_outstanding_bat_ogm_packet
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:94 [inline]
dump_stack_lvl+0x71/0xa0 lib/dump_stack.c:120
print_address_description mm/kasan/report.c:378 [inline]
print_report+0x174/0x4f6 mm/kasan/report.c:482
kasan_report+0xce/0x100 mm/kasan/report.c:595
batadv_iv_ogm_aggr_packet net/batman-adv/bat_iv_ogm.c:326 [inline]
batadv_iv_ogm_send_to_if net/batman-adv/bat_iv_ogm.c:352 [inline]
batadv_iv_ogm_emit net/batman-adv/bat_iv_ogm.c:419 [inline]
batadv_iv_send_outstanding_bat_ogm_packet+0xa4a/0xb10 net/batman-adv/bat_iv_ogm.c:1700
process_one_work+0x66e/0xfb0 kernel/workqueue.c:3288
process_scheduled_works kernel/workqueue.c:3371 [inline]
worker_thread+0x4b4/0xb80 kernel/workqueue.c:3452
kthread+0x300/0x3d0 kernel/kthread.c:436
ret_from_fork+0x41b/0x6b0 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
</TASK>
Affected kernel version range:
Latest (tested on commit c1f49dea2b8f ("Merge tag 'mm-hotfixes-stable-2026-04-19-00-14' of git://
git.kernel.org/pub/scm/linux/kernel/git/akpm/mm"))
Description of the problem and suspected location of the bug:
After debugging the reproducer generated by Syzkaller, we think the trace is misleading. Our research led us to a possible integer overflow. The variable is located in /net/batman-adv/bat_iv_ogm.c, function batadv_iv_ogm_send_to_if, line 338: s16 buff_pos. This variable is incremented in the loop below in order to find the location of the next packet. However, the size check is done in batadv_iv_ogm_aggr_packet (same file, line 315), using this time an int. This leads to a wrap around in the buff_pos variable as the checks are done using int not s16.
Reproducer:
You will find attached to this mail the .config file we used with the C reproducer generated by Syzkaller (we compiled it using gcc repro.c -o repro -static). We used the create_image.sh script provided by Syzkaller to generate a debian trixie environment (
https://github.com/google/syzkaller/blob/master/tools/create-image.sh). We launched it using this qemu command that you can find in Syzkaller documentation (
https://github.com/google/syzkaller/blob/master/docs/linux/setup_ubuntu-host_qemu-vm_x86-64-kernel.md) :
qemu-system-x86_64 \
-m 2G \
-smp 2 \
-kernel <bzImage path> \
-append "console=ttyS0 kasan.fault=panic root=/dev/sda earlyprintk=serial net.ifnames=0" \
-drive file=<trixie.img path>,format=raw \
-net user,host=10.0.2.10,hostfwd=tcp:127.0.0.1:10021-:22 \
-net nic,model=e1000 \
-nographic \
-enable-kvm \
-pidfile vm.pid -s \
2>&1 | tee vm.log
Our fuzzing implementation is still a work in progress. Thus, our environment setup in the fuzzer leverages system to run the interface setup commands. You will find them in the reproducer, therefore you will not need to manually do this when running the reproducer.
/usr/sbin/ip tuntap add mode tap dev syz_tun
/usr/sbin/ip link add name bat0 type batadv
/usr/sbin/ip link set dev syz_tun master bat0
/usr/sbin/ip link set dev bat0 mtu 1532
/usr/sbin/ip link set dev syz_tun mtu 1532
Conditions:
While testing, we had all this config options enabled:
CONFIG_BATMAN_ADV=y
CONFIG_BATMAN_ADV_BATMAN_V=y
CONFIG_BATMAN_ADV_BLA=y
CONFIG_BATMAN_ADV_DAT=y
CONFIG_BATMAN_ADV_MCAST=y
CONFIG_BATMAN_ADV_DEBUG=y
CONFIG_BATMAN_ADV_TRACING=y
A proposed fix:
After finding the overflow, we decided to match the types of the variables. As the size check is done using int, we changed the type of buff_pos from s16 to int. We ran the reproducer against this patch version, and we did not have any KASAN output. However, we are not familiar enough with the BATMAN protocol to know if this breaks the code from the protocol perspective.
You will find below the proposed patch:
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index f28e9cbf8ad5..618d1889c04e 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -335,7 +335,7 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
struct batadv_priv *bat_priv = netdev_priv(hard_iface->mesh_iface);
const char *fwd_str;
u8 packet_num;
- s16 buff_pos;
+ int buff_pos;
struct batadv_ogm_packet *batadv_ogm_packet;
struct sk_buff *skb;
u8 *packet_pos;
This is our first security report in linux kernel, do not hesitate to tell us if we did something wrong.
Have a good day,
Alexis and Lyes