[Bluetooth] Prevent RFCOMM connections through the RAW socket
This patch adds additional checks to prevent RFCOMM connections be established through the RAW socket interface. Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:
@@ -363,6 +363,11 @@ static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sk->sk_type != SOCK_STREAM) {
|
||||||
|
err = -EINVAL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
write_lock_bh(&rfcomm_sk_list.lock);
|
write_lock_bh(&rfcomm_sk_list.lock);
|
||||||
|
|
||||||
if (sa->rc_channel && __rfcomm_get_sock_by_addr(sa->rc_channel, &sa->rc_bdaddr)) {
|
if (sa->rc_channel && __rfcomm_get_sock_by_addr(sa->rc_channel, &sa->rc_bdaddr)) {
|
||||||
@@ -393,14 +398,18 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a
|
|||||||
if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_rc))
|
if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_rc))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND)
|
|
||||||
return -EBADFD;
|
|
||||||
|
|
||||||
if (sk->sk_type != SOCK_STREAM)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
lock_sock(sk);
|
lock_sock(sk);
|
||||||
|
|
||||||
|
if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) {
|
||||||
|
err = -EBADFD;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sk->sk_type != SOCK_STREAM) {
|
||||||
|
err = -EINVAL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
sk->sk_state = BT_CONNECT;
|
sk->sk_state = BT_CONNECT;
|
||||||
bacpy(&bt_sk(sk)->dst, &sa->rc_bdaddr);
|
bacpy(&bt_sk(sk)->dst, &sa->rc_bdaddr);
|
||||||
rfcomm_pi(sk)->channel = sa->rc_channel;
|
rfcomm_pi(sk)->channel = sa->rc_channel;
|
||||||
@@ -410,6 +419,7 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a
|
|||||||
err = bt_sock_wait_state(sk, BT_CONNECTED,
|
err = bt_sock_wait_state(sk, BT_CONNECTED,
|
||||||
sock_sndtimeo(sk, flags & O_NONBLOCK));
|
sock_sndtimeo(sk, flags & O_NONBLOCK));
|
||||||
|
|
||||||
|
done:
|
||||||
release_sock(sk);
|
release_sock(sk);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -428,6 +438,11 @@ static int rfcomm_sock_listen(struct socket *sock, int backlog)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sk->sk_type != SOCK_STREAM) {
|
||||||
|
err = -EINVAL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
if (!rfcomm_pi(sk)->channel) {
|
if (!rfcomm_pi(sk)->channel) {
|
||||||
bdaddr_t *src = &bt_sk(sk)->src;
|
bdaddr_t *src = &bt_sk(sk)->src;
|
||||||
u8 channel;
|
u8 channel;
|
||||||
@@ -472,6 +487,11 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sk->sk_type != SOCK_STREAM) {
|
||||||
|
err = -EINVAL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
|
timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
|
||||||
|
|
||||||
BT_DBG("sk %p timeo %ld", sk, timeo);
|
BT_DBG("sk %p timeo %ld", sk, timeo);
|
||||||
|
Reference in New Issue
Block a user