diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2009-01-16 04:06:13 -0500 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2009-02-27 00:14:33 -0500 |
commit | 0588d94fd7e414367a7ae517569d2222441c255f (patch) | |
tree | c8563ce159bbea94e57df39a9b27bb1628ebccdd /net/bluetooth/l2cap.c | |
parent | f62e4323ab43c59e7cd7f72c1eb392d7c767ce5a (diff) |
Bluetooth: Restrict application of socket options
The new socket options should only be evaluated for SOL_BLUETOOTH level
and not for every other level. Previously this causes some minor issues
when detecting if a kernel with certain features is available.
Also restrict BT_SECURITY to SOCK_SEQPACKET for L2CAP and SOCK_STREAM for
the RFCOMM protocol.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/l2cap.c')
-rw-r--r-- | net/bluetooth/l2cap.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index b2d279c245cf..82a9e692baed 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -1248,10 +1248,18 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch | |||
1248 | if (level == SOL_L2CAP) | 1248 | if (level == SOL_L2CAP) |
1249 | return l2cap_sock_setsockopt_old(sock, optname, optval, optlen); | 1249 | return l2cap_sock_setsockopt_old(sock, optname, optval, optlen); |
1250 | 1250 | ||
1251 | if (level != SOL_BLUETOOTH) | ||
1252 | return -ENOPROTOOPT; | ||
1253 | |||
1251 | lock_sock(sk); | 1254 | lock_sock(sk); |
1252 | 1255 | ||
1253 | switch (optname) { | 1256 | switch (optname) { |
1254 | case BT_SECURITY: | 1257 | case BT_SECURITY: |
1258 | if (sk->sk_type != SOCK_SEQPACKET) { | ||
1259 | err = -EINVAL; | ||
1260 | break; | ||
1261 | } | ||
1262 | |||
1255 | sec.level = BT_SECURITY_LOW; | 1263 | sec.level = BT_SECURITY_LOW; |
1256 | 1264 | ||
1257 | len = min_t(unsigned int, sizeof(sec), optlen); | 1265 | len = min_t(unsigned int, sizeof(sec), optlen); |
@@ -1384,6 +1392,9 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch | |||
1384 | if (level == SOL_L2CAP) | 1392 | if (level == SOL_L2CAP) |
1385 | return l2cap_sock_getsockopt_old(sock, optname, optval, optlen); | 1393 | return l2cap_sock_getsockopt_old(sock, optname, optval, optlen); |
1386 | 1394 | ||
1395 | if (level != SOL_BLUETOOTH) | ||
1396 | return -ENOPROTOOPT; | ||
1397 | |||
1387 | if (get_user(len, optlen)) | 1398 | if (get_user(len, optlen)) |
1388 | return -EFAULT; | 1399 | return -EFAULT; |
1389 | 1400 | ||
@@ -1391,6 +1402,11 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch | |||
1391 | 1402 | ||
1392 | switch (optname) { | 1403 | switch (optname) { |
1393 | case BT_SECURITY: | 1404 | case BT_SECURITY: |
1405 | if (sk->sk_type != SOCK_SEQPACKET) { | ||
1406 | err = -EINVAL; | ||
1407 | break; | ||
1408 | } | ||
1409 | |||
1394 | sec.level = l2cap_pi(sk)->sec_level; | 1410 | sec.level = l2cap_pi(sk)->sec_level; |
1395 | 1411 | ||
1396 | len = min_t(unsigned int, len, sizeof(sec)); | 1412 | len = min_t(unsigned int, len, sizeof(sec)); |