All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexandru Hossu <hossu.alexandru@gmail.com>
To: linux-bluetooth@vger.kernel.org
Cc: marcel@holtmann.org, luiz.dentz@gmail.com
Subject: Bluetooth: L2CAP: missing length check before __unpack_control() in l2cap_data_rcv()
Date: Fri, 15 May 2026 03:29:20 -0700 (PDT)	[thread overview]
Message-ID: <6a06f580.7c7532bd.18b472.cf27@mx.google.com> (raw)

Hi,

I found an out-of-bounds read in l2cap_data_rcv() in net/bluetooth/l2cap_core.c.

__unpack_control() at line 1070 is called without verifying the skb contains
enough bytes. The function reads 2 bytes (enhanced control) or 4 bytes
(extended control) from skb->data unconditionally:

    __unpack_enhanced_control(get_unaligned_le16(skb->data), ...);
    __unpack_extended_control(get_unaligned_le32(skb->data), ...);

The check at l2cap_recv_frame() line 6935 does not protect this. That check
is: if (len != skb->len). When the attacker sends a 0-byte PDU body with
header len=0, after skb_pull(L2CAP_HDR_SIZE) both len and skb->len are 0.
The comparison 0 != 0 is false so the frame is not dropped.

The result is a 2 or 4 byte read past the end of the skb data region.
After the call, skb_pull() for the control field size on the 0-byte skb
returns NULL (len > skb->len soft check at skb_pull_inline:2851), leaving
skb->len at 0 and the subsequent len = skb->len read also 0.

Trigger: send a 0-byte data PDU on an established ERTM or STREAMING channel.
Classic BT, adjacent radio range. Unauthenticated ACL connection is enough.

Suggested fix at the top of l2cap_data_rcv():

    u16 ctrl_size = test_bit(FLAG_EXT_CTRL, &chan->flags) ?
                    L2CAP_EXT_CTRL_SIZE : L2CAP_ENH_CTRL_SIZE;
    if (skb->len < ctrl_size) {
        kfree_skb(skb);
        return -EINVAL;
    }

Tested on linux-next commit e98d21c170b0 (2026-05-08).

Alexandru

                 reply	other threads:[~2026-05-15 10:29 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=6a06f580.7c7532bd.18b472.cf27@mx.google.com \
    --to=hossu.alexandru@gmail.com \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=luiz.dentz@gmail.com \
    --cc=marcel@holtmann.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.