Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Bluetooth: vhci: Fix info leak in force_devcd_write()

There are a number of bugs here:

1) If "count" is less than sizeof(dump_data.data) then it copies
uninitialized data.
2) If simple_write_to_buffer() returns -EFAULT then we run into a
problem "ret < count" comparison. "count" is an unsigned long so the
comparison is type promoted to unsigned long and the negative returns
become high positive values. That also results in copying
uninitialized data.
3) If "*ppos" is non-zero then the first part of the dump_data
buffer is uninitialized. Using copy_from_user() instead of
simple_write_to_buffer() is more appropriate here.

Fixes: d5d5df6da0aa ("Bluetooth: Add vhci devcoredump support")
Signed-off-by: Dan Carpenter <error27@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

authored by

Dan Carpenter and committed by
Luiz Augusto von Dentz
e4eea890 0811ff48

+10 -6
+10 -6
drivers/bluetooth/hci_vhci.c
··· 323 323 struct hci_dev *hdev = data->hdev; 324 324 struct sk_buff *skb = NULL; 325 325 struct devcoredump_test_data dump_data; 326 + size_t data_size; 326 327 int ret; 327 328 328 - ret = simple_write_to_buffer(&dump_data, sizeof(dump_data), ppos, 329 - user_buf, count); 330 - if (ret < count) 331 - return ret; 329 + if (count < offsetof(struct devcoredump_test_data, data) || 330 + count > sizeof(dump_data)) 331 + return -EINVAL; 332 332 333 - skb = alloc_skb(sizeof(dump_data.data), GFP_ATOMIC); 333 + if (copy_from_user(&dump_data, user_buf, count)) 334 + return -EFAULT; 335 + 336 + data_size = count - offsetof(struct devcoredump_test_data, data); 337 + skb = alloc_skb(data_size, GFP_ATOMIC); 334 338 if (!skb) 335 339 return -ENOMEM; 336 - skb_put_data(skb, &dump_data.data, sizeof(dump_data.data)); 340 + skb_put_data(skb, &dump_data.data, data_size); 337 341 338 342 hci_devcd_register(hdev, vhci_coredump, vhci_coredump_hdr, NULL); 339 343