Browse Source

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>
David S. Miller 9 years ago
parent
commit
5c1f5b457b

+ 1 - 1
net/bluetooth/af_bluetooth.c

@@ -250,7 +250,7 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 
 
 	skb_free_datagram(sk, skb);
 	skb_free_datagram(sk, skb);
 
 
-	if (msg->msg_flags & MSG_TRUNC)
+	if (flags & MSG_TRUNC)
 		copied = skblen;
 		copied = skblen;
 
 
 	return err ? : copied;
 	return err ? : copied;

+ 2 - 0
net/bluetooth/hci_request.c

@@ -262,6 +262,8 @@ int __hci_req_sync(struct hci_dev *hdev, int (*func)(struct hci_request *req,
 		break;
 		break;
 	}
 	}
 
 
+	kfree_skb(hdev->req_skb);
+	hdev->req_skb = NULL;
 	hdev->req_status = hdev->req_result = 0;
 	hdev->req_status = hdev->req_result = 0;
 
 
 	BT_DBG("%s end: err %d", hdev->name, err);
 	BT_DBG("%s end: err %d", hdev->name, err);

+ 1 - 1
net/bluetooth/hci_sock.c

@@ -1091,7 +1091,7 @@ static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg,
 
 
 	skb_free_datagram(sk, skb);
 	skb_free_datagram(sk, skb);
 
 
-	if (msg->msg_flags & MSG_TRUNC)
+	if (flags & MSG_TRUNC)
 		copied = skblen;
 		copied = skblen;
 
 
 	return err ? : copied;
 	return err ? : copied;

+ 8 - 0
net/bluetooth/l2cap_core.c

@@ -32,6 +32,7 @@
 
 
 #include <linux/debugfs.h>
 #include <linux/debugfs.h>
 #include <linux/crc16.h>
 #include <linux/crc16.h>
+#include <linux/filter.h>
 
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 #include <net/bluetooth/hci_core.h>
@@ -5835,6 +5836,9 @@ static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
 		if (chan->sdu)
 		if (chan->sdu)
 			break;
 			break;
 
 
+		if (!pskb_may_pull(skb, L2CAP_SDULEN_SIZE))
+			break;
+
 		chan->sdu_len = get_unaligned_le16(skb->data);
 		chan->sdu_len = get_unaligned_le16(skb->data);
 		skb_pull(skb, L2CAP_SDULEN_SIZE);
 		skb_pull(skb, L2CAP_SDULEN_SIZE);
 
 
@@ -6610,6 +6614,10 @@ static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
 		goto drop;
 		goto drop;
 	}
 	}
 
 
+	if ((chan->mode == L2CAP_MODE_ERTM ||
+	     chan->mode == L2CAP_MODE_STREAMING) && sk_filter(chan->data, skb))
+		goto drop;
+
 	if (!control->sframe) {
 	if (!control->sframe) {
 		int err;
 		int err;
 
 

+ 12 - 2
net/bluetooth/l2cap_sock.c

@@ -1019,7 +1019,7 @@ static int l2cap_sock_recvmsg(struct socket *sock, struct msghdr *msg,
 		goto done;
 		goto done;
 
 
 	if (pi->rx_busy_skb) {
 	if (pi->rx_busy_skb) {
-		if (!sock_queue_rcv_skb(sk, pi->rx_busy_skb))
+		if (!__sock_queue_rcv_skb(sk, pi->rx_busy_skb))
 			pi->rx_busy_skb = NULL;
 			pi->rx_busy_skb = NULL;
 		else
 		else
 			goto done;
 			goto done;
@@ -1270,7 +1270,17 @@ static int l2cap_sock_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
 		goto done;
 		goto done;
 	}
 	}
 
 
-	err = sock_queue_rcv_skb(sk, skb);
+	if (chan->mode != L2CAP_MODE_ERTM &&
+	    chan->mode != L2CAP_MODE_STREAMING) {
+		/* Even if no filter is attached, we could potentially
+		 * get errors from security modules, etc.
+		 */
+		err = sk_filter(sk, skb);
+		if (err)
+			goto done;
+	}
+
+	err = __sock_queue_rcv_skb(sk, skb);
 
 
 	/* For ERTM, handle one skb that doesn't fit into the recv
 	/* For ERTM, handle one skb that doesn't fit into the recv
 	 * buffer.  This is important to do because the data frames
 	 * buffer.  This is important to do because the data frames