From 73f706314a089ad4fa2de6b5e1fb835a5eadb052 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Fri, 5 Apr 2013 14:57:34 +0200 Subject: [PATCH] Bluetooth: hidp: verify l2cap sockets commit b3916db32c4a3124eee9f3742a2f4723731d7602 upstream. We need to verify that the given sockets actually are l2cap sockets. If they aren't, we are not supposed to access bt_sk(sock) and we shouldn't start the session if the offsets turn out to be valid local BT addresses. That is, if someone passes a TCP socket to HIDCONNADD, then we access some random offset in the TCP socket (which isn't even guaranteed to be valid). Fix this by checking that the socket is an l2cap socket. Change-Id: I401bca741588b34876a1c835d8d4567852b4ec75 Signed-off-by: David Herrmann Acked-by: Marcel Holtmann Signed-off-by: Gustavo Padovan Signed-off-by: Ben Hutchings Signed-off-by: Francisco Franco --- include/net/bluetooth/l2cap.h | 1 + net/bluetooth/hidp/core.c | 2 ++ net/bluetooth/l2cap_sock.c | 6 ++++++ 3 files changed, 9 insertions(+) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 8e281b41588e..4d3212bb7f19 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -667,6 +667,7 @@ extern struct bt_sock_list l2cap_sk_list; int l2cap_init_sockets(void); void l2cap_cleanup_sockets(void); +bool l2cap_is_socket(struct socket *sock); u8 l2cap_get_ident(struct l2cap_conn *conn); void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data); diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 8fc2658c2c2a..080c765ba2a0 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -849,6 +849,8 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, BT_DBG(""); + if (!l2cap_is_socket(ctrl_sock) || !l2cap_is_socket(intr_sock)) + return -EINVAL; if (bacmp(&bt_sk(ctrl_sock->sk)->src, &bt_sk(intr_sock->sk)->src) || bacmp(&bt_sk(ctrl_sock->sk)->dst, &bt_sk(intr_sock->sk)->dst)) return -ENOTUNIQ; diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index e71af74ea7c6..e312df5611d5 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -124,6 +124,12 @@ static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src) return sk; } +bool l2cap_is_socket(struct socket *sock) +{ + return sock && sock->ops == &l2cap_sock_ops; +} +EXPORT_SYMBOL(l2cap_is_socket); + static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) { struct sock *sk = sock->sk;