CVE-2011-2497: Linux kernel Bluetooth L2CAP Remote Heap Memory Corruption
This was discovered and reported some time ago by Dan Rosenberg (aka bliss) as we can read here. The exact vulnerable code is available in net/bluetooth/l2cap_core.c file.
static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) { struct l2cap_conf_req *req = (struct l2cap_conf_req *) data; u16 dcid, flags; u8 rsp[64]; struct sock *sk; int len; dcid = __le16_to_cpu(req->dcid); flags = __le16_to_cpu(req->flags); ... /* Reject if config buffer is too small. */ len = cmd_len - sizeof(*req); if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) { l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, L2CAP_CONF_REJECT, flags), rsp); goto unlock; } /* Store config. */ memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len); l2cap_pi(sk)->conf_len += len; ... unlock: bh_unlock_sock(sk); return 0; } ... static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) { int err = 0; switch (cmd->code) { ... case L2CAP_CONF_REQ: err = l2cap_config_req(conn, cmd, cmd_len, data); break; ... default: BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code); err = -EINVAL; break; } return err; }
This code is part of Linux kernel’s implementation of L2CAP Bluetooth protocol. More specifically, the l2cap_bredr_sig_cmd() will trigger the call to l2cap_config_req() in case of a ‘L2CAP_CONF_REQ’ signaling command.
Now, if we move to l2cap_config_req() we will see that the signed integer ‘len’ is initialized with the value of ‘cmd_len’ (command length) minus the request’s size. If this results in an integer underflow, the subsequent check in the ‘if’ clause could be bypassed due to the addition with ‘l2cap_pi(sk)->conf_len’ and the final call to memcpy() passing ‘len’ as an argument could result in kernel heap memory corruption.
So, by providing a small command size value a remote attacker could trigger this bug. At last, the fix dor this vulnerability was to add a check for negative values of ‘len’ as shown below.
len = cmd_len - sizeof(*req); - if (chan->conf_len + len > sizeof(chan->conf_req)) { + if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) { l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(chan, rsp, L2CAP_CONF_REJECT, flags), rsp);
You can also see that the l2cap_pi()s have been removed but this was part of a different patch, irrelevant to this issue.
awsome ;)
proller
July 13, 2011 at 20:19
Nice blog right here! Also your web site loads up fast! What
web host are you the use of? Can I am getting your affiliate hyperlink for your host?
I want my website loaded up as quickly as yours lol
top laptops
June 5, 2013 at 17:16