Skip to contentSkip to conversation

Pull request: bluetooth-2.6 2010-03-21

PATCH New Marcel Holtmann 2 participants 5 messages Mar 21, 2010 – Mar 22, 2010

Subsystems (3)
lore
Share & tools
lore

Marcel Holtmann

author maintainer
#0 lore raw

Hi Dave,

these patches fix a potential remote denial of service in the L2CAP layer and a potential bad memory access with some sysfs files.

As agreed with Linus, I fixed the sysfs issue in two steps. The first patch just avoids the invalid memory access while accepting that the content might be truncated. The second patch moves everything over to debugfs (where these files belong anyway) and switches to seq_file.

This two step approach allows an easy backport to -stable kernel by only picking the first patch.

Linus, feel free to pull directly since both patches are security related and should be merged as quickly as possible.

Regards

Marcel

Please pull from

git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6.git master

This will update the following files:

 include/net/bluetooth/bluetooth.h |    2 +-
 net/bluetooth/hci_sysfs.c         |    3 +-
 net/bluetooth/l2cap.c             |   48 +++++++++++++++++++++++++++----------
 net/bluetooth/rfcomm/core.c       |   41 ++++++++++++++++++++++---------
 net/bluetooth/rfcomm/sock.c       |   38 ++++++++++++++++++++--------
 net/bluetooth/sco.c               |   38 ++++++++++++++++++++---------
 6 files changed, 119 insertions(+), 51 deletions(-)

through these ChangeSets:

Andrei Emeltchenko (1):
Bluetooth: Fix kernel crash on L2CAP stress tests

Marcel Holtmann (2):
Bluetooth: Fix potential bad memory access with sysfs files
Bluetooth: Convert debug files to actually use debugfs instead of sysfs

author maintainer
#1 lore raw

PATCH 1/3 Bluetooth: Fix potential bad memory access with sysfs files

When creating a high number of Bluetooth sockets (L2CAP, SCO and RFCOMM) it is possible to scribble repeatedly on arbitrary pages of memory. Ensure that the content of these sysfs files is always less than one page. Even if this means truncating. The files in question are scheduled to be moved over to debugfs in the future anyway.

Based on initial patches from Neil Brown and Linus Torvalds

---
 net/bluetooth/l2cap.c       |   10 +++++++++-
 net/bluetooth/rfcomm/core.c |   13 ++++++++++++-
 net/bluetooth/rfcomm/sock.c |   11 ++++++++++-
 net/bluetooth/sco.c         |   11 ++++++++++-
 4 files changed, 41 insertions(+), 4 deletions(-)
net/bluetooth/l2cap.c +9 -1
index 4db7ae2..2755182 100644
@@ -3944,16 +3944,24 @@ static ssize_t l2cap_sysfs_show(struct class *dev,
 	struct sock *sk;
 	struct hlist_node *node;
 	char *str = buf;
+	int size = PAGE_SIZE;
 
 	read_lock_bh(&l2cap_sk_list.lock);
 
 	sk_for_each(sk, node, &l2cap_sk_list.head) {
 		struct l2cap_pinfo *pi = l2cap_pi(sk);
+		int len;
 
-		str += sprintf(str, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
+		len = snprintf(str, size, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
 				batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
 				sk->sk_state, __le16_to_cpu(pi->psm), pi->scid,
 				pi->dcid, pi->imtu, pi->omtu, pi->sec_level);
+
+		size -= len;
+		if (size <= 0)
+			break;
+
+		str += len;
 	}
 
 	read_unlock_bh(&l2cap_sk_list.lock);
net/bluetooth/rfcomm/core.c +12 -1
index db8a68e..cf16407 100644
@@ -2105,6 +2105,7 @@ static ssize_t rfcomm_dlc_sysfs_show(struct class *dev,
 	struct rfcomm_session *s;
 	struct list_head *pp, *p;
 	char *str = buf;
+	int size = PAGE_SIZE;
 
 	rfcomm_lock();
 
@@ -2113,11 +2114,21 @@ static ssize_t rfcomm_dlc_sysfs_show(struct class *dev,
 		list_for_each(pp, &s->dlcs) {
 			struct sock *sk = s->sock->sk;
 			struct rfcomm_dlc *d = list_entry(pp, struct rfcomm_dlc, list);
+			int len;
 
-			str += sprintf(str, "%s %s %ld %d %d %d %d\n",
+			len = snprintf(str, size, "%s %s %ld %d %d %d %d\n",
 					batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
 					d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits);
+
+			size -= len;
+			if (size <= 0)
+				break;
+
+			str += len;
 		}
+
+		if (size <= 0)
+			break;
 	}
 
 	rfcomm_unlock();
net/bluetooth/rfcomm/sock.c +10 -1
index ca87d6a..8d0ee0b 100644
@@ -1068,13 +1068,22 @@ static ssize_t rfcomm_sock_sysfs_show(struct class *dev,
 	struct sock *sk;
 	struct hlist_node *node;
 	char *str = buf;
+	int size = PAGE_SIZE;
 
 	read_lock_bh(&rfcomm_sk_list.lock);
 
 	sk_for_each(sk, node, &rfcomm_sk_list.head) {
-		str += sprintf(str, "%s %s %d %d\n",
+		int len;
+
+		len = snprintf(str, size, "%s %s %d %d\n",
 				batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
 				sk->sk_state, rfcomm_pi(sk)->channel);
+
+		size -= len;
+		if (size <= 0)
+			break;
+
+		str += len;
 	}
 
 	read_unlock_bh(&rfcomm_sk_list.lock);
net/bluetooth/sco.c +10 -1
index f93b939..967a751 100644
@@ -960,13 +960,22 @@ static ssize_t sco_sysfs_show(struct class *dev,
 	struct sock *sk;
 	struct hlist_node *node;
 	char *str = buf;
+	int size = PAGE_SIZE;
 
 	read_lock_bh(&sco_sk_list.lock);
 
 	sk_for_each(sk, node, &sco_sk_list.head) {
-		str += sprintf(str, "%s %s %d\n",
+		int len;
+
+		len = snprintf(str, size, "%s %s %d\n",
 				batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
 				sk->sk_state);
+
+		size -= len;
+		if (size <= 0)
+			break;
+
+		str += len;
 	}
 
 	read_unlock_bh(&sco_sk_list.lock);
Signature · 1 line
1.6.6.1
author maintainer
#2 lore raw

PATCH 2/3 Bluetooth: Convert debug files to actually use debugfs instead of sysfs

Some of the debug files ended up wrongly in sysfs, because at that point of time, debugfs didn't exist. Convert these files to use debugfs and also seq_file. This patch converts all of these files at once and then removes the exported symbol for the Bluetooth sysfs class.

---
 include/net/bluetooth/bluetooth.h |    2 +-
 net/bluetooth/hci_sysfs.c         |    3 +-
 net/bluetooth/l2cap.c             |   51 +++++++++++++++++++++---------------
 net/bluetooth/rfcomm/core.c       |   52 ++++++++++++++++++++----------------
 net/bluetooth/rfcomm/sock.c       |   47 +++++++++++++++++++--------------
 net/bluetooth/sco.c               |   47 ++++++++++++++++++---------------
 6 files changed, 114 insertions(+), 88 deletions(-)
include/net/bluetooth/bluetooth.h +1 -1
index 04a6908..ff77e8f 100644
@@ -176,6 +176,6 @@ extern void hci_sock_cleanup(void);
 extern int bt_sysfs_init(void);
 extern void bt_sysfs_cleanup(void);
 
-extern struct class *bt_class;
+extern struct dentry *bt_debugfs;
 
 #endif /* __BLUETOOTH_H */
net/bluetooth/hci_sysfs.c +1 -2
index cafb55b..05fd125 100644
@@ -8,8 +8,7 @@
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 
-struct class *bt_class = NULL;
-EXPORT_SYMBOL_GPL(bt_class);
+static struct class *bt_class;
 
 struct dentry *bt_debugfs = NULL;
 EXPORT_SYMBOL_GPL(bt_debugfs);
net/bluetooth/l2cap.c +30 -21

90 lines not on this page · raw message

net/bluetooth/rfcomm/core.c +29 -23

93 lines not on this page · raw message

net/bluetooth/rfcomm/sock.c +27 -20

85 lines not on this page · raw message

net/bluetooth/sco.c +26 -21

84 lines not on this page · raw message

Signature · 1 line
1.6.6.1
author maintainer
#3 lore raw

PATCH 3/3 Bluetooth: Fix kernel crash on L2CAP stress tests

From: Andrei Emeltchenko <[email protected]>

Added very simple check that req buffer has enough space to fit configuration parameters. Shall be enough to reject packets with configuration size more than req buffer.

Crash trace below

[ 6069.659393] Unable to handle kernel paging request at virtual address 02000205
[ 6069.673034] Internal error: Oops: 805 [#1] PREEMPT
...
[ 6069.727172] PC is at l2cap_add_conf_opt+0x70/0xf0 [l2cap]
[ 6069.732604] LR is at l2cap_recv_frame+0x1350/0x2e78 [l2cap]
...
[ 6070.030303] Backtrace:
[ 6070.032806] [<bf1c2880>] (l2cap_add_conf_opt+0x0/0xf0 [l2cap]) from
[<bf1c6624>] (l2cap_recv_frame+0x1350/0x2e78 [l2cap])
[ 6070.043823]  r8:dc5d3100 r7:df2a91d6 r6:00000001 r5:df2a8000 r4:00000200
[ 6070.050659] [<bf1c52d4>] (l2cap_recv_frame+0x0/0x2e78 [l2cap]) from
[<bf1c8408>] (l2cap_recv_acldata+0x2bc/0x350 [l2cap])
[ 6070.061798] [<bf1c814c>] (l2cap_recv_acldata+0x0/0x350 [l2cap]) from
[<bf0037a4>] (hci_rx_task+0x244/0x478 [bluetooth])
[ 6070.072631]  r6:dc647700 r5:00000001 r4:df2ab740
[ 6070.077362] [<bf003560>] (hci_rx_task+0x0/0x478 [bluetooth]) from
[<c006b9fc>] (tasklet_action+0x78/0xd8)
[ 6070.087005] [<c006b984>] (tasklet_action+0x0/0xd8) from [<c006c160>]
---
 net/bluetooth/l2cap.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)
net/bluetooth/l2cap.c +5 -0
index 43e17f7..7794a2e 100644
@@ -2832,6 +2832,11 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
 			int len = cmd->len - sizeof(*rsp);
 			char req[64];
 
+			if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
+				l2cap_send_disconn_req(conn, sk);
+				goto done;
+			}
+
 			/* throw out any old stored conf requests */
 			result = L2CAP_CONF_SUCCESS;
 			len = l2cap_parse_conf_rsp(sk, rsp->data,
Signature · 1 line
1.6.6.1
maintainer
#4 lore raw
In reply to Marcel Holtmann

From: Marcel Holtmann <[email protected]>
Date: Sun, 21 Mar 2010 06:41:34 +0100

Quoted 2 lines

these patches fix a potential remote denial of service in the L2CAP layer and a potential bad memory access with some sysfs files.

I've pulled this in thanks Marcel.