summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2012-10-19 20:10:46 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-11-26 12:14:18 -0800
commit9437e9d67094de0a69de1585b28932d6ac2b1911 (patch)
tree5fbe76111b308f8cfa6a25d0454cac06bc4dff62
parentc322410c338e617342312c0a7418708ee9187c1a (diff)
downloadlwn-9437e9d67094de0a69de1585b28932d6ac2b1911.tar.gz
lwn-9437e9d67094de0a69de1585b28932d6ac2b1911.zip
Bluetooth: Fix having bogus entries in mgmt_read_index_list reply
commit 476e44cb19f1fbf2d5883dddcc0ce31b33b45915 upstream. The mgmt_read_index_list uses one loop to calculate the max needed size of its response with the help of an upper-bound of the controller count. The second loop is more strict as it checks for HCI_SETUP (which might have gotten set after the first loop) and could result in some indexes being skipped. Because of this the function needs to readjust the event length and index count after filling in the response array. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Acked-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--net/bluetooth/mgmt.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index eba022de3c20..534250ada18d 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -321,7 +321,7 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data,
struct hci_dev *d;
size_t rp_len;
u16 count;
- int i, err;
+ int err;
BT_DBG("sock %p", sk);
@@ -339,17 +339,18 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data,
return -ENOMEM;
}
- rp->num_controllers = cpu_to_le16(count);
-
- i = 0;
+ count = 0;
list_for_each_entry(d, &hci_dev_list, list) {
if (test_bit(HCI_SETUP, &d->dev_flags))
continue;
- rp->index[i++] = cpu_to_le16(d->id);
+ rp->index[count++] = cpu_to_le16(d->id);
BT_DBG("Added hci%u", d->id);
}
+ rp->num_controllers = cpu_to_le16(count);
+ rp_len = sizeof(*rp) + (2 * count);
+
read_unlock(&hci_dev_list_lock);
err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST, 0, rp,