summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'tags/2.6.18-11/30014_bluetooth-l2cap-hci-info-leaks.patch')
-rw-r--r--tags/2.6.18-11/30014_bluetooth-l2cap-hci-info-leaks.patch63
1 files changed, 63 insertions, 0 deletions
diff --git a/tags/2.6.18-11/30014_bluetooth-l2cap-hci-info-leaks.patch b/tags/2.6.18-11/30014_bluetooth-l2cap-hci-info-leaks.patch
new file mode 100644
index 0000000..0c64d1d
--- /dev/null
+++ b/tags/2.6.18-11/30014_bluetooth-l2cap-hci-info-leaks.patch
@@ -0,0 +1,63 @@
+From: Marcel Holtmann <marcel@holtmann.org>
+Date: Fri, 4 May 2007 22:35:59 +0000 (+0200)
+Subject: [Bluetooth] Fix L2CAP and HCI setsockopt() information leaks
+X-Git-Tag: v2.6.22-rc1~822^2~2^2~6
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=0878b6667f28772aa7d6b735abff53efc7bf6d91
+
+[Bluetooth] Fix L2CAP and HCI setsockopt() information leaks
+
+The L2CAP and HCI setsockopt() implementations have a small information
+leak that makes it possible to leak kernel stack memory to userspace.
+
+If the optlen parameter is 0, no data will be copied by copy_from_user(),
+but the uninitialized stack buffer will be read and stored later. A call
+to getsockopt() can now retrieve the leaked information.
+
+To fix this problem the stack buffer given to copy_from_user() must be
+initialized with the current settings.
+
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+---
+
+diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
+index 832b5f4..bfc9a35 100644
+--- a/net/bluetooth/hci_sock.c
++++ b/net/bluetooth/hci_sock.c
+@@ -499,6 +499,15 @@ static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char
+ break;
+
+ case HCI_FILTER:
++ {
++ struct hci_filter *f = &hci_pi(sk)->filter;
++
++ uf.type_mask = f->type_mask;
++ uf.opcode = f->opcode;
++ uf.event_mask[0] = *((u32 *) f->event_mask + 0);
++ uf.event_mask[1] = *((u32 *) f->event_mask + 1);
++ }
++
+ len = min_t(unsigned int, len, sizeof(uf));
+ if (copy_from_user(&uf, optval, len)) {
+ err = -EFAULT;
+diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
+index a586787..a59b1fb 100644
+--- a/net/bluetooth/l2cap.c
++++ b/net/bluetooth/l2cap.c
+@@ -954,11 +954,17 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
+
+ switch (optname) {
+ case L2CAP_OPTIONS:
++ opts.imtu = l2cap_pi(sk)->imtu;
++ opts.omtu = l2cap_pi(sk)->omtu;
++ opts.flush_to = l2cap_pi(sk)->flush_to;
++ opts.mode = 0x00;
++
+ len = min_t(unsigned int, sizeof(opts), optlen);
+ if (copy_from_user((char *) &opts, optval, len)) {
+ err = -EFAULT;
+ break;
+ }
++
+ l2cap_pi(sk)->imtu = opts.imtu;
+ l2cap_pi(sk)->omtu = opts.omtu;
+ break;