aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2009-01-16 04:06:13 -0500
committerMarcel Holtmann <marcel@holtmann.org>2009-02-27 00:14:33 -0500
commit0588d94fd7e414367a7ae517569d2222441c255f (patch)
treec8563ce159bbea94e57df39a9b27bb1628ebccdd /net/bluetooth
parentf62e4323ab43c59e7cd7f72c1eb392d7c767ce5a (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.c16
-rw-r--r--net/bluetooth/rfcomm/sock.c16
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));