* [PATCH] Bluetooth: bnep: reject short frames before parsing
@ 2026-05-13 3:12 Zhang Cen
2026-05-13 4:41 ` bluez.test.bot
0 siblings, 1 reply; 2+ messages in thread
From: Zhang Cen @ 2026-05-13 3:12 UTC (permalink / raw)
To: Marcel Holtmann, Luiz Augusto von Dentz
Cc: linux-bluetooth, linux-kernel, zerocling0077, 2045gemini,
Zhang Cen
An L2CAP peer can deliver an empty BNEP payload or a payload that contains
only the outer type byte. bnep_rx_frame() currently dereferences the type
byte and, for control traffic, the control opcode before it proves that
those bytes exist in the skb. The setup-connection control path can also
read the setup size byte before it is present. bnep_rx_control() has the
same problem when it is asked to parse an empty control payload.
Reject empty skbs before reading the outer type byte, require a control
opcode before parsing BNEP_CONTROL, require the setup size byte before
using it, and make bnep_rx_control() fail zero-length control payloads.
Sanitizer validation reported:
KASAN slab-out-of-bounds in bnep_rx_frame()
Read of size 1
Call trace:
dump_stack_lvl() (?:?)
print_address_description() (mm/kasan/report.c:373)
bnep_rx_frame() (net/bluetooth/bnep/core.c:306)
print_report() (?:?)
__virt_addr_valid() (?:?)
srso_alias_return_thunk() (arch/x86/include/asm/nospec-branch.h:375)
kasan_addr_to_slab() (mm/kasan/common.c:45)
kasan_report() (?:?)
process_one_work() (kernel/workqueue.c:3200)
worker_thread() (?:?)
__kthread_parkme() (kernel/kthread.c:259)
kthread() (?:?)
_raw_spin_unlock_irq() (kernel/locking/spinlock.c:204)
ret_from_fork() (?:?)
__switch_to() (?:?)
ret_from_fork_asm() (?:?)
kasan_save_stack() (mm/kasan/common.c:52)
kasan_save_track() (mm/kasan/common.c:74)
__kasan_kmalloc() (?:?)
vpanic() (kernel/panic.c:576)
panic() (?:?)
preempt_schedule_common() (kernel/sched/core.c:7352)
preempt_schedule_thunk() (?:?)
end_report() (mm/kasan/report.c:219)
Signed-off-by: Zhang Cen <rollkingzzc@gmail.com>
---
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index d44987d4515c..f5070bbd6b57 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -208,9 +208,14 @@ static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len)
static int bnep_rx_control(struct bnep_session *s, void *data, int len)
{
- u8 cmd = *(u8 *)data;
+ u8 cmd;
int err = 0;
+ if (len < 1)
+ return -EILSEQ;
+
+ cmd = *(u8 *)data;
+
data++;
len--;
@@ -303,14 +308,21 @@ static int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
dev->stats.rx_bytes += skb->len;
+ if (skb->len < 1)
+ goto badframe;
+
type = *(u8 *) skb->data;
skb_pull(skb, 1);
- ctrl_type = *(u8 *)skb->data;
if ((type & BNEP_TYPE_MASK) >= sizeof(__bnep_rx_hlen))
goto badframe;
if ((type & BNEP_TYPE_MASK) == BNEP_CONTROL) {
+ if (skb->len < 1)
+ goto badframe;
+
+ ctrl_type = *(u8 *)skb->data;
+
if (bnep_rx_control(s, skb->data, skb->len) < 0) {
dev->stats.tx_errors++;
kfree_skb(skb);
@@ -326,6 +338,9 @@ static int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
switch (ctrl_type) {
case BNEP_SETUP_CONN_REQ:
/* Pull: ctrl type (1 b), len (1 b), data (len bytes) */
+ if (skb->len < 2)
+ goto badframe;
+
if (!skb_pull(skb, 2 + *(u8 *)(skb->data + 1) * 2))
goto badframe;
break;
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-05-13 4:41 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-13 3:12 [PATCH] Bluetooth: bnep: reject short frames before parsing Zhang Cen
2026-05-13 4:41 ` bluez.test.bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox