diff options
author | David S. Miller <davem@davemloft.net> | 2016-08-27 00:09:17 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-08-27 00:09:17 -0400 |
commit | 5c1f5b457b86a263d0e21c8f3ebe83d515e7bcce (patch) | |
tree | ec02b3022cd3c983591a9599d3ad3b39d2fe2bf7 | |
parent | c15e07b02bf0450bc8e60f2cc51cb42daa371417 (diff) | |
parent | 4f34228b67246ae3b3ab1dc33b980c77c0650ef4 (diff) |
Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth
Johan Hedberg says:
====================
pull request: bluetooth 2016-08-25
Here are a couple of important Bluetooth fixes for the 4.8 kernel:
- Memory leak fix for HCI requests
- Fix sk_filter handling with L2CAP
- Fix sock_recvmsg behavior when MSG_TRUNC is not set
Please let me know if there are any issues pulling. Thanks.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/bluetooth/af_bluetooth.c | 2 | ||||
-rw-r--r-- | net/bluetooth/hci_request.c | 2 | ||||
-rw-r--r-- | net/bluetooth/hci_sock.c | 2 | ||||
-rw-r--r-- | net/bluetooth/l2cap_core.c | 8 | ||||
-rw-r--r-- | net/bluetooth/l2cap_sock.c | 14 |
5 files changed, 24 insertions, 4 deletions
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index ece45e0683fd..0b5f729d08d2 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
@@ -250,7 +250,7 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, | |||
250 | 250 | ||
251 | skb_free_datagram(sk, skb); | 251 | skb_free_datagram(sk, skb); |
252 | 252 | ||
253 | if (msg->msg_flags & MSG_TRUNC) | 253 | if (flags & MSG_TRUNC) |
254 | copied = skblen; | 254 | copied = skblen; |
255 | 255 | ||
256 | return err ? : copied; | 256 | return err ? : copied; |
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index c045b3c54768..b0e23dfc5c34 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c | |||
@@ -262,6 +262,8 @@ int __hci_req_sync(struct hci_dev *hdev, int (*func)(struct hci_request *req, | |||
262 | break; | 262 | break; |
263 | } | 263 | } |
264 | 264 | ||
265 | kfree_skb(hdev->req_skb); | ||
266 | hdev->req_skb = NULL; | ||
265 | hdev->req_status = hdev->req_result = 0; | 267 | hdev->req_status = hdev->req_result = 0; |
266 | 268 | ||
267 | BT_DBG("%s end: err %d", hdev->name, err); | 269 | BT_DBG("%s end: err %d", hdev->name, err); |
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 6ef8a01a9ad4..96f04b7b9556 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
@@ -1091,7 +1091,7 @@ static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, | |||
1091 | 1091 | ||
1092 | skb_free_datagram(sk, skb); | 1092 | skb_free_datagram(sk, skb); |
1093 | 1093 | ||
1094 | if (msg->msg_flags & MSG_TRUNC) | 1094 | if (flags & MSG_TRUNC) |
1095 | copied = skblen; | 1095 | copied = skblen; |
1096 | 1096 | ||
1097 | return err ? : copied; | 1097 | return err ? : copied; |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 54ceb1f2cc9a..d4cad29b033f 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -32,6 +32,7 @@ | |||
32 | 32 | ||
33 | #include <linux/debugfs.h> | 33 | #include <linux/debugfs.h> |
34 | #include <linux/crc16.h> | 34 | #include <linux/crc16.h> |
35 | #include <linux/filter.h> | ||
35 | 36 | ||
36 | #include <net/bluetooth/bluetooth.h> | 37 | #include <net/bluetooth/bluetooth.h> |
37 | #include <net/bluetooth/hci_core.h> | 38 | #include <net/bluetooth/hci_core.h> |
@@ -5835,6 +5836,9 @@ static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, | |||
5835 | if (chan->sdu) | 5836 | if (chan->sdu) |
5836 | break; | 5837 | break; |
5837 | 5838 | ||
5839 | if (!pskb_may_pull(skb, L2CAP_SDULEN_SIZE)) | ||
5840 | break; | ||
5841 | |||
5838 | chan->sdu_len = get_unaligned_le16(skb->data); | 5842 | chan->sdu_len = get_unaligned_le16(skb->data); |
5839 | skb_pull(skb, L2CAP_SDULEN_SIZE); | 5843 | skb_pull(skb, L2CAP_SDULEN_SIZE); |
5840 | 5844 | ||
@@ -6610,6 +6614,10 @@ static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) | |||
6610 | goto drop; | 6614 | goto drop; |
6611 | } | 6615 | } |
6612 | 6616 | ||
6617 | if ((chan->mode == L2CAP_MODE_ERTM || | ||
6618 | chan->mode == L2CAP_MODE_STREAMING) && sk_filter(chan->data, skb)) | ||
6619 | goto drop; | ||
6620 | |||
6613 | if (!control->sframe) { | 6621 | if (!control->sframe) { |
6614 | int err; | 6622 | int err; |
6615 | 6623 | ||
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 1842141baedb..a8ba752732c9 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -1019,7 +1019,7 @@ static int l2cap_sock_recvmsg(struct socket *sock, struct msghdr *msg, | |||
1019 | goto done; | 1019 | goto done; |
1020 | 1020 | ||
1021 | if (pi->rx_busy_skb) { | 1021 | if (pi->rx_busy_skb) { |
1022 | if (!sock_queue_rcv_skb(sk, pi->rx_busy_skb)) | 1022 | if (!__sock_queue_rcv_skb(sk, pi->rx_busy_skb)) |
1023 | pi->rx_busy_skb = NULL; | 1023 | pi->rx_busy_skb = NULL; |
1024 | else | 1024 | else |
1025 | goto done; | 1025 | goto done; |
@@ -1270,7 +1270,17 @@ static int l2cap_sock_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) | |||
1270 | goto done; | 1270 | goto done; |
1271 | } | 1271 | } |
1272 | 1272 | ||
1273 | err = sock_queue_rcv_skb(sk, skb); | 1273 | if (chan->mode != L2CAP_MODE_ERTM && |
1274 | chan->mode != L2CAP_MODE_STREAMING) { | ||
1275 | /* Even if no filter is attached, we could potentially | ||
1276 | * get errors from security modules, etc. | ||
1277 | */ | ||
1278 | err = sk_filter(sk, skb); | ||
1279 | if (err) | ||
1280 | goto done; | ||
1281 | } | ||
1282 | |||
1283 | err = __sock_queue_rcv_skb(sk, skb); | ||
1274 | 1284 | ||
1275 | /* For ERTM, handle one skb that doesn't fit into the recv | 1285 | /* For ERTM, handle one skb that doesn't fit into the recv |
1276 | * buffer. This is important to do because the data frames | 1286 | * buffer. This is important to do because the data frames |