[PATCH 5/8] Bluetooth: Lock socket when reading HCI socket options
From: Marcel Holtmann <marcel@holtmann.org>
Date: 2012-02-20 10:58:37
Subsystem:
bluetooth subsystem, the rest · Maintainers:
Marcel Holtmann, Luiz Augusto von Dentz, Linus Torvalds
When reading the HCI raw socket option, the socket was never locked. So lock the socket and in addition return EINVAL on non raw sockets. Signed-off-by: Marcel Holtmann <marcel@holtmann.org> --- net/bluetooth/hci_sock.c | 23 +++++++++++++++++------ 1 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 3d86aa6..d729dd7 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c@@ -677,11 +677,20 @@ static int hci_sock_getsockopt(struct socket *sock, int level, int optname, char { struct hci_ufilter uf; struct sock *sk = sock->sk; - int len, opt; + int len, opt, err = 0; + + BT_DBG("sk %p, opt %d", sk, optname); if (get_user(len, optlen)) return -EFAULT; + lock_sock(sk); + + if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) { + err = -EINVAL; + goto done; + } + switch (optname) { case HCI_DATA_DIR: if (hci_pi(sk)->cmsg_mask & HCI_CMSG_DIR)
@@ -690,7 +699,7 @@ static int hci_sock_getsockopt(struct socket *sock, int level, int optname, char opt = 0; if (put_user(opt, optval)) - return -EFAULT; + err = -EFAULT; break; case HCI_TIME_STAMP:
@@ -700,7 +709,7 @@ static int hci_sock_getsockopt(struct socket *sock, int level, int optname, char opt = 0; if (put_user(opt, optval)) - return -EFAULT; + err = -EFAULT; break; case HCI_FILTER:
@@ -715,15 +724,17 @@ static int hci_sock_getsockopt(struct socket *sock, int level, int optname, char len = min_t(unsigned int, len, sizeof(uf)); if (copy_to_user(optval, &uf, len)) - return -EFAULT; + err = -EFAULT; break; default: - return -ENOPROTOOPT; + err = -ENOPROTOOPT; break; } - return 0; +done: + release_sock(sk); + return err; } static const struct proto_ops hci_sock_ops = {
--
1.7.7.6