aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2010-03-15 17:12:58 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-04-01 19:02:13 -0400
commita318674438c789f5bf46a91cf24b5988b2091f16 (patch)
tree8b06bfb539b09d4778622ff2c65af0e1881d53cb /net
parent3ecee16aa4617db7cb756ad01526d395dc86d95f (diff)
Bluetooth: Fix potential bad memory access with sysfs files
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>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/l2cap.c10
-rw-r--r--net/bluetooth/rfcomm/core.c13
-rw-r--r--net/bluetooth/rfcomm/sock.c11
-rw-r--r--net/bluetooth/sco.c11
4 files changed, 41 insertions, 4 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 400efa26ddba..4609d9c94f41 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -3942,16 +3942,24 @@ static ssize_t l2cap_sysfs_show(struct class *dev, char *buf)
3942 struct sock *sk; 3942 struct sock *sk;
3943 struct hlist_node *node; 3943 struct hlist_node *node;
3944 char *str = buf; 3944 char *str = buf;
3945 int size = PAGE_SIZE;
3945 3946
3946 read_lock_bh(&l2cap_sk_list.lock); 3947 read_lock_bh(&l2cap_sk_list.lock);
3947 3948
3948 sk_for_each(sk, node, &l2cap_sk_list.head) { 3949 sk_for_each(sk, node, &l2cap_sk_list.head) {
3949 struct l2cap_pinfo *pi = l2cap_pi(sk); 3950 struct l2cap_pinfo *pi = l2cap_pi(sk);
3951 int len;
3950 3952
3951 str += sprintf(str, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n", 3953 len = snprintf(str, size, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
3952 batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), 3954 batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
3953 sk->sk_state, __le16_to_cpu(pi->psm), pi->scid, 3955 sk->sk_state, __le16_to_cpu(pi->psm), pi->scid,
3954 pi->dcid, pi->imtu, pi->omtu, pi->sec_level); 3956 pi->dcid, pi->imtu, pi->omtu, pi->sec_level);
3957
3958 size -= len;
3959 if (size <= 0)
3960 break;
3961
3962 str += len;
3955 } 3963 }
3956 3964
3957 read_unlock_bh(&l2cap_sk_list.lock); 3965 read_unlock_bh(&l2cap_sk_list.lock);
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 89f4a59eb82b..3fe9c7c1d517 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -2103,6 +2103,7 @@ static ssize_t rfcomm_dlc_sysfs_show(struct class *dev, char *buf)
2103 struct rfcomm_session *s; 2103 struct rfcomm_session *s;
2104 struct list_head *pp, *p; 2104 struct list_head *pp, *p;
2105 char *str = buf; 2105 char *str = buf;
2106 int size = PAGE_SIZE;
2106 2107
2107 rfcomm_lock(); 2108 rfcomm_lock();
2108 2109
@@ -2111,11 +2112,21 @@ static ssize_t rfcomm_dlc_sysfs_show(struct class *dev, char *buf)
2111 list_for_each(pp, &s->dlcs) { 2112 list_for_each(pp, &s->dlcs) {
2112 struct sock *sk = s->sock->sk; 2113 struct sock *sk = s->sock->sk;
2113 struct rfcomm_dlc *d = list_entry(pp, struct rfcomm_dlc, list); 2114 struct rfcomm_dlc *d = list_entry(pp, struct rfcomm_dlc, list);
2115 int len;
2114 2116
2115 str += sprintf(str, "%s %s %ld %d %d %d %d\n", 2117 len = snprintf(str, size, "%s %s %ld %d %d %d %d\n",
2116 batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), 2118 batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
2117 d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits); 2119 d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits);
2120
2121 size -= len;
2122 if (size <= 0)
2123 break;
2124
2125 str += len;
2118 } 2126 }
2127
2128 if (size <= 0)
2129 break;
2119 } 2130 }
2120 2131
2121 rfcomm_unlock(); 2132 rfcomm_unlock();
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 4b5968dda673..bc03b508f35e 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -1066,13 +1066,22 @@ static ssize_t rfcomm_sock_sysfs_show(struct class *dev, char *buf)
1066 struct sock *sk; 1066 struct sock *sk;
1067 struct hlist_node *node; 1067 struct hlist_node *node;
1068 char *str = buf; 1068 char *str = buf;
1069 int size = PAGE_SIZE;
1069 1070
1070 read_lock_bh(&rfcomm_sk_list.lock); 1071 read_lock_bh(&rfcomm_sk_list.lock);
1071 1072
1072 sk_for_each(sk, node, &rfcomm_sk_list.head) { 1073 sk_for_each(sk, node, &rfcomm_sk_list.head) {
1073 str += sprintf(str, "%s %s %d %d\n", 1074 int len;
1075
1076 len = snprintf(str, size, "%s %s %d %d\n",
1074 batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), 1077 batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
1075 sk->sk_state, rfcomm_pi(sk)->channel); 1078 sk->sk_state, rfcomm_pi(sk)->channel);
1079
1080 size -= len;
1081 if (size <= 0)
1082 break;
1083
1084 str += len;
1076 } 1085 }
1077 1086
1078 read_unlock_bh(&rfcomm_sk_list.lock); 1087 read_unlock_bh(&rfcomm_sk_list.lock);
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index dd8f6ec57dce..66cab63e76e3 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -958,13 +958,22 @@ static ssize_t sco_sysfs_show(struct class *dev, char *buf)
958 struct sock *sk; 958 struct sock *sk;
959 struct hlist_node *node; 959 struct hlist_node *node;
960 char *str = buf; 960 char *str = buf;
961 int size = PAGE_SIZE;
961 962
962 read_lock_bh(&sco_sk_list.lock); 963 read_lock_bh(&sco_sk_list.lock);
963 964
964 sk_for_each(sk, node, &sco_sk_list.head) { 965 sk_for_each(sk, node, &sco_sk_list.head) {
965 str += sprintf(str, "%s %s %d\n", 966 int len;
967
968 len = snprintf(str, size, "%s %s %d\n",
966 batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), 969 batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
967 sk->sk_state); 970 sk->sk_state);
971
972 size -= len;
973 if (size <= 0)
974 break;
975
976 str += len;
968 } 977 }
969 978
970 read_unlock_bh(&sco_sk_list.lock); 979 read_unlock_bh(&sco_sk_list.lock);