diff options
author | Mat Martineau <mathewm@codeaurora.org> | 2010-09-08 13:05:26 -0400 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2010-10-12 11:44:51 -0400 |
commit | 0fba2558cbb3fae3a09147b7d6e18a6204204e0e (patch) | |
tree | 48f5424c4b3530a2b39f5e5bc164db194ae10ae3 /net/bluetooth/l2cap.c | |
parent | 08601469a5aac8b3453d8aca0b8f9bd8dfdae12c (diff) |
Bluetooth: Validate PSM values in calls to connect() and bind()
Valid L2CAP PSMs are odd numbers, and the least significant bit of the
most significant byte must be 0.
Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/l2cap.c')
-rw-r--r-- | net/bluetooth/l2cap.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 0b54b7dd8401..2f625b87a89e 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -1008,10 +1008,20 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) | |||
1008 | goto done; | 1008 | goto done; |
1009 | } | 1009 | } |
1010 | 1010 | ||
1011 | if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 && | 1011 | if (la.l2_psm) { |
1012 | !capable(CAP_NET_BIND_SERVICE)) { | 1012 | __u16 psm = __le16_to_cpu(la.l2_psm); |
1013 | err = -EACCES; | 1013 | |
1014 | goto done; | 1014 | /* PSM must be odd and lsb of upper byte must be 0 */ |
1015 | if ((psm & 0x0101) != 0x0001) { | ||
1016 | err = -EINVAL; | ||
1017 | goto done; | ||
1018 | } | ||
1019 | |||
1020 | /* Restrict usage of well-known PSMs */ | ||
1021 | if (psm < 0x1001 && !capable(CAP_NET_BIND_SERVICE)) { | ||
1022 | err = -EACCES; | ||
1023 | goto done; | ||
1024 | } | ||
1015 | } | 1025 | } |
1016 | 1026 | ||
1017 | write_lock_bh(&l2cap_sk_list.lock); | 1027 | write_lock_bh(&l2cap_sk_list.lock); |
@@ -1190,6 +1200,13 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al | |||
1190 | goto done; | 1200 | goto done; |
1191 | } | 1201 | } |
1192 | 1202 | ||
1203 | /* PSM must be odd and lsb of upper byte must be 0 */ | ||
1204 | if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 && | ||
1205 | sk->sk_type != SOCK_RAW) { | ||
1206 | err = -EINVAL; | ||
1207 | goto done; | ||
1208 | } | ||
1209 | |||
1193 | /* Set destination address and psm */ | 1210 | /* Set destination address and psm */ |
1194 | bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr); | 1211 | bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr); |
1195 | l2cap_pi(sk)->psm = la.l2_psm; | 1212 | l2cap_pi(sk)->psm = la.l2_psm; |