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/rfcomm/sock.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/rfcomm/sock.c')
-rw-r--r-- | net/bluetooth/rfcomm/sock.c | 16 |
1 files changed, 16 insertions, 0 deletions
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)); |