Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0588d94f authored by Marcel Holtmann's avatar Marcel Holtmann
Browse files

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: default avatarMarcel Holtmann <marcel@holtmann.org>
parent f62e4323
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -1248,10 +1248,18 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
	if (level == SOL_L2CAP)
		return l2cap_sock_setsockopt_old(sock, optname, optval, optlen);

	if (level != SOL_BLUETOOTH)
		return -ENOPROTOOPT;

	lock_sock(sk);

	switch (optname) {
	case BT_SECURITY:
		if (sk->sk_type != SOCK_SEQPACKET) {
			err = -EINVAL;
			break;
		}

		sec.level = BT_SECURITY_LOW;

		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
	if (level == SOL_L2CAP)
		return l2cap_sock_getsockopt_old(sock, optname, optval, optlen);

	if (level != SOL_BLUETOOTH)
		return -ENOPROTOOPT;

	if (get_user(len, optlen))
		return -EFAULT;

@@ -1391,6 +1402,11 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch

	switch (optname) {
	case BT_SECURITY:
		if (sk->sk_type != SOCK_SEQPACKET) {
			err = -EINVAL;
			break;
		}

		sec.level = l2cap_pi(sk)->sec_level;

		len = min_t(unsigned int, len, sizeof(sec));
+16 −0
Original line number Diff line number Diff line
@@ -778,10 +778,18 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c
	if (level == SOL_RFCOMM)
		return rfcomm_sock_setsockopt_old(sock, optname, optval, optlen);

	if (level != SOL_BLUETOOTH)
		return -ENOPROTOOPT;

	lock_sock(sk);

	switch (optname) {
	case BT_SECURITY:
		if (sk->sk_type != SOCK_STREAM) {
			err = -EINVAL;
			break;
		}

		sec.level = BT_SECURITY_LOW;

		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
	if (level == SOL_RFCOMM)
		return rfcomm_sock_getsockopt_old(sock, optname, optval, optlen);

	if (level != SOL_BLUETOOTH)
		return -ENOPROTOOPT;

	if (get_user(len, optlen))
		return -EFAULT;

@@ -906,6 +917,11 @@ static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, c

	switch (optname) {
	case BT_SECURITY:
		if (sk->sk_type != SOCK_STREAM) {
			err = -EINVAL;
			break;
		}

		sec.level = rfcomm_pi(sk)->sec_level;

		len = min_t(unsigned int, len, sizeof(sec));