]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
Bluetooth: L2CAP: validate connectionless PSM length
authorSamuel Moelius <sam.moelius@trailofbits.com>
Mon, 8 Jun 2026 23:57:05 +0000 (23:57 +0000)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Thu, 11 Jun 2026 18:24:41 +0000 (14:24 -0400)
Connectionless L2CAP frames carry a two-byte PSM at the start of the
payload.  l2cap_recv_frame() currently reads that PSM unconditionally
after validating only the outer L2CAP length.

A malformed connectionless frame with a zero- or one-byte payload can
therefore make the parser read beyond the advertised skb payload and use
tailroom bytes as part of the PSM.  A VHCI-backed QEMU reproducer
injected a one-byte connectionless payload and reached the unchecked
read.

Reject connectionless frames that cannot contain the PSM before reading
or pulling it.  This preserves all valid connectionless frames while
dropping only structurally incomplete packets.

Assisted-by: Codex:gpt-5.5-cyber-preview
Signed-off-by: Samuel Moelius <sam.moelius@trailofbits.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
net/bluetooth/l2cap_core.c

index a97d492473e299e0a45237206b115595a2c04e82..62133eef9d2fea14e7bf8d203fc951f4ed4499b4 100644 (file)
@@ -7029,6 +7029,11 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
                break;
 
        case L2CAP_CID_CONN_LESS:
+               if (skb->len < L2CAP_PSMLEN_SIZE) {
+                       kfree_skb(skb);
+                       break;
+               }
+
                psm = get_unaligned((__le16 *) skb->data);
                skb_pull(skb, L2CAP_PSMLEN_SIZE);
                l2cap_conless_channel(conn, psm, skb);