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 | |
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')
-rw-r--r-- | net/bluetooth/l2cap.c | 16 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/sock.c | 16 |
2 files changed, 32 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)); |
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 9986ef35c890..7f482784e9f7 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -778,10 +778,18 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c | |||
778 | if (level == SOL_RFCOMM) | 778 | if (level == SOL_RFCOMM) |
779 | return rfcomm_sock_setsockopt_old(sock, optname, optval, optlen); | 779 | return rfcomm_sock_setsockopt_old(sock, optname, optval, optlen); |
780 | 780 | ||
781 | if (level != SOL_BLUETOOTH) | ||
782 | return -ENOPROTOOPT; | ||
783 | |||
781 | lock_sock(sk); | 784 | lock_sock(sk); |
782 | 785 | ||
783 | switch (optname) { | 786 | switch (optname) { |
784 | case BT_SECURITY: | 787 | case BT_SECURITY: |
788 | if (sk->sk_type != SOCK_STREAM) { | ||
789 | err = -EINVAL; | ||
790 | break; | ||
791 | } | ||
792 | |||
785 | sec.level = BT_SECURITY_LOW; | 793 | sec.level = BT_SECURITY_LOW; |
786 | 794 | ||
787 | len = min_t(unsigned int, sizeof(sec), optlen); | 795 | len = min_t(unsigned int, sizeof(sec), optlen); |
@@ -899,6 +907,9 @@ static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, c | |||
899 | if (level == SOL_RFCOMM) | 907 | if (level == SOL_RFCOMM) |
900 | return rfcomm_sock_getsockopt_old(sock, optname, optval, optlen); | 908 | return rfcomm_sock_getsockopt_old(sock, optname, optval, optlen); |
901 | 909 | ||
910 | if (level != SOL_BLUETOOTH) | ||
911 | return -ENOPROTOOPT; | ||
912 | |||
902 | if (get_user(len, optlen)) | 913 | if (get_user(len, optlen)) |
903 | return -EFAULT; | 914 | return -EFAULT; |
904 | 915 | ||
@@ -906,6 +917,11 @@ static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, c | |||
906 | 917 | ||
907 | switch (optname) { | 918 | switch (optname) { |
908 | case BT_SECURITY: | 919 | case BT_SECURITY: |
920 | if (sk->sk_type != SOCK_STREAM) { | ||
921 | err = -EINVAL; | ||
922 | break; | ||
923 | } | ||
924 | |||
909 | sec.level = rfcomm_pi(sk)->sec_level; | 925 | sec.level = rfcomm_pi(sk)->sec_level; |
910 | 926 | ||
911 | len = min_t(unsigned int, len, sizeof(sec)); | 927 | len = min_t(unsigned int, len, sizeof(sec)); |