Two information leaks in the setsockopt() handling of the Bluetooth subsystem. We assigned CVE-2007-1353 to it. The root cause for both issues is exactly the same and so we only used one CVE name.
The impact is low
The Bluetooth L2CAP setsockopt code has a small information leak. Basically there is a case where 32 bits of kernel stack memory can get leaked to userland in l2cap_sock_setsockopt():
static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen)
{
struct sock *sk = sock->sk;
struct l2cap_options opts;
…
switch (optname) {
case L2CAP_OPTIONS:
len = min_t(unsigned int, sizeof(opts), optlen); <-- len can be 0 !!!
if (copy_from_user((char *) &opts, optval, len)) { <-- no data copied
err = -EFAULT;
break;
}
l2cap_pi(sk)->imtu = opts.imtu; <-- uninit
l2cap_pi(sk)->omtu = opts.omtu; <-- uninit
break;
…
}
So optlen can be 0, so no data is copied into opts, and so whatever is on the stack at that point will get put in the sk struct. You could use getsockopt() to retrieve that leaked data.
Seems the hci_sock_setsockopt() function has a very simular information leak in
the HCI_FILTER case:
case HCI_FILTER:
len = min_t(unsigned int, len, sizeof(uf)); <-- can be 0
if (copy_from_user(&uf, optval, len)) { <-- no data copied
So uf remains uninit. A call to getsockopt can retrieved the leaked info.
[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.
---
commit 85d8a7cda30a511b340f91e2d8ab597689324f84
tree 44700efaac2e640a060dc28229f96dbcf17b6cc5
parent 28defbea64622f69d65a6079bf800cedb9915a5f
author Marcel
committer Marcel
net/bluetooth/hci_sock.c | 9 +++++++++
net/bluetooth/l2cap.c | 6 ++++++
2 files changed, 15 insertions(+), 0 deletions(-)
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 71f5cfb..db9eb49 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 e83ee82..767a0d3 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;
--- IDENTIFIER = WIND00113330
WIND00113331.zip is for 1.4
WIND00113332.zip is for 1.5
WIND00113333.zip is for 2.0
1. Unzip the patch under [install_dir]/updates
2. Install the patch CD by entering the patch CD directory and run setup_linux.
3. This is a source only patch so you will have to build the kernel
4. Issue a make fs and make the kernel in a configured directory.
5. Upload the kernel and rootfs into the target and boot it up.