mirror of
https://github.com/torvalds/linux.git
synced 2026-09-25 09:41:03 +02:00
Bluetooth: bnep: fix out-of-bounds reads on short RX/TX frames and control fallthrough
Fix multiple out-of-bounds reads in Bluetooth BNEP frame processing:
1. In bnep_rx_frame() and bnep_ctrl_frame() (net/bluetooth/bnep/core.c),
use pskb_may_pull() to verify the BNEP header, control type byte,
filter count, and extension headers exist before reading them, and
return 0 after handling BNEP_CONTROL instead of falling through to
Ethernet frame submission when no extension headers follow.
2. In bnep_net_xmit() (net/bluetooth/bnep/netdev.c), verify skb->len >=
ETH_HLEN with pskb_may_pull() before reading the 14-byte Ethernet
header to prevent an out-of-bounds heap read and infoleak on short
AF_PACKET TX frames.
Fixes: 1da177e4c3 ("Linux-2.6.12-rc2")
Assisted-by: LLM
Signed-off-by: Hui Peng <benquike@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
b5dbb41b21
commit
f0ca020cbb
|
|
@ -270,9 +270,14 @@ static int bnep_rx_extension(struct bnep_session *s, struct sk_buff *skb)
|
|||
|
||||
BT_DBG("type 0x%x len %u", h->type, h->len);
|
||||
|
||||
if (skb->len < h->len) {
|
||||
err = -EILSEQ;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (h->type & BNEP_TYPE_MASK) {
|
||||
case BNEP_EXT_CONTROL:
|
||||
bnep_rx_control(s, skb->data, skb->len);
|
||||
bnep_rx_control(s, skb->data, h->len);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -373,6 +378,11 @@ static int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
|
|||
goto badframe;
|
||||
}
|
||||
|
||||
if ((type & BNEP_TYPE_MASK) == BNEP_CONTROL) {
|
||||
kfree_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Strip 802.1p header */
|
||||
if (ntohs(s->eh.h_proto) == ETH_P_8021Q) {
|
||||
if (!skb_pull(skb, 4))
|
||||
|
|
@ -451,6 +461,11 @@ static int bnep_tx_frame(struct bnep_session *s, struct sk_buff *skb)
|
|||
goto send;
|
||||
}
|
||||
|
||||
if (skb->len < ETH_HLEN) {
|
||||
kfree_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
iv[il++] = (struct kvec) { &type, 1 };
|
||||
len++;
|
||||
|
||||
|
|
|
|||
|
|
@ -166,6 +166,12 @@ static netdev_tx_t bnep_net_xmit(struct sk_buff *skb,
|
|||
|
||||
BT_DBG("skb %p, dev %p", skb, dev);
|
||||
|
||||
if (!pskb_may_pull(skb, ETH_HLEN)) {
|
||||
dev->stats.tx_dropped++;
|
||||
kfree_skb(skb);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BT_BNEP_MC_FILTER
|
||||
if (bnep_net_mc_filter(skb, s)) {
|
||||
kfree_skb(skb);
|
||||
|
|
@ -218,7 +224,7 @@ void bnep_net_setup(struct net_device *dev)
|
|||
dev->addr_len = ETH_ALEN;
|
||||
|
||||
ether_setup(dev);
|
||||
dev->min_mtu = 0;
|
||||
dev->min_mtu = ETH_MIN_MTU;
|
||||
dev->max_mtu = ETH_MAX_MTU;
|
||||
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
|
||||
dev->netdev_ops = &bnep_netdev_ops;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user