lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Thu, 28 Dec 2017 16:59:12 +0000
From:   Ben Hutchings <ben@...adent.org.uk>
To:     linux-kernel@...r.kernel.org, stable@...r.kernel.org
CC:     akpm@...ux-foundation.org,
        "David Herrmann" <dh.herrmann@...il.com>,
        "Gustavo Padovan" <gustavo.padovan@...labora.co.uk>,
        "Marcel Holtmann" <marcel@...tmann.org>
Subject: [PATCH 3.2 84/94] Bluetooth: hidp: verify l2cap sockets

3.2.97-rc1 review patch.  If anyone has any objections, please let me know.

------------------

From: David Herrmann <dh.herrmann@...il.com>

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.

Signed-off-by: David Herrmann <dh.herrmann@...il.com>
Acked-by: Marcel Holtmann <marcel@...tmann.org>
Signed-off-by: Gustavo Padovan <gustavo.padovan@...labora.co.uk>
Signed-off-by: Ben Hutchings <ben@...adent.org.uk>
---
 include/net/bluetooth/l2cap.h | 1 +
 net/bluetooth/hidp/core.c     | 2 ++
 net/bluetooth/l2cap_sock.c    | 6 ++++++
 3 files changed, 9 insertions(+)

--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -496,6 +496,7 @@ extern int disable_ertm;
 
 int l2cap_init_sockets(void);
 void l2cap_cleanup_sockets(void);
+bool l2cap_is_socket(struct socket *sock);
 
 void __l2cap_connect_rsp_defer(struct l2cap_chan *chan);
 int __l2cap_wait_ack(struct sock *sk);
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -972,6 +972,8 @@ int hidp_add_connection(struct hidp_conn
 
 	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;
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -38,6 +38,12 @@ static const struct proto_ops l2cap_sock
 static void l2cap_sock_init(struct sock *sk, struct sock *parent);
 static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio);
 
+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;

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ