lkml.org 
[lkml]   [2010]   [Mar]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[150/156] Bluetooth: Fix potential bad memory access with sysfs files
2.6.33-stable review patch.  If anyone has any objections, please let us know.

------------------

From: Marcel Holtmann <marcel@holtmann.org>

commit 101545f6fef4a0a3ea8daf0b5b880df2c6a92a69 upstream.

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

Reported-by: Neil Brown <neilb@suse.de>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
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(-)

--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -3942,16 +3942,24 @@ static ssize_t l2cap_sysfs_show(struct c
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);
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -2103,6 +2103,7 @@ static ssize_t rfcomm_dlc_sysfs_show(str
struct rfcomm_session *s;
struct list_head *pp, *p;
char *str = buf;
+ int size = PAGE_SIZE;

rfcomm_lock();

@@ -2111,11 +2112,21 @@ static ssize_t rfcomm_dlc_sysfs_show(str
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();
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -1066,13 +1066,22 @@ static ssize_t rfcomm_sock_sysfs_show(st
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);
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -958,13 +958,22 @@ static ssize_t sco_sysfs_show(struct cla
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);



\
 
 \ /
  Last update: 2010-03-31 01:29    [W:1.062 / U:0.992 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site