summaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/legacy
diff options
context:
space:
mode:
authorAndrzej Pietrasiewicz <andrzej.p@samsung.com>2015-03-03 10:52:07 +0100
committerFelipe Balbi <balbi@ti.com>2015-03-10 15:33:34 -0500
commitc69b8186945c10d245586e9f9703486e9574170c (patch)
tree80efc8e1166f18f7972b82c8600d7af7450682bc /drivers/usb/gadget/legacy
parent050f571264154b2f5b4c3c4c1581ab365064ff28 (diff)
downloadop-kernel-dev-c69b8186945c10d245586e9f9703486e9574170c.zip
op-kernel-dev-c69b8186945c10d245586e9f9703486e9574170c.tar.gz
usb: gadget: printer: eliminate random pointer dereference
struct printer_dev contains 3 list heads: tx_reqs, rx_reqs and rx_buffers. There is just one instance of this structure in the driver and it is file static, and as such initialized with all zeros. If device_create() or cdev_add() fails then "goto fail" branch is taken, which results in printer_cfg_unbind() call. The latter checks if tx_reqs, rx_reqs and rx_buffers lists are empty. The check for emptiness is in fact a check whether the "next" member of struct list_head points to the head of the list. But the heads of the lists in question have not been initialized yet and, as mentioned above, contain all zeros, so list_empty() returns false and respective "while" loop body starts executing. Here, container_of() just subtracts the offset of a struct usb_request member from an address of this same member, which results in a value somewhere near 0 or 0xfff...ff. And the argument to list_del() dereferences such a pointer which causes a disaster. This patch moves respective INIT_LIST_HEAD() invocations to a point before "goto fail" branch can be taken. Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/gadget/legacy')
-rw-r--r--drivers/usb/gadget/legacy/printer.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c
index 21ea317..12247d3 100644
--- a/drivers/usb/gadget/legacy/printer.c
+++ b/drivers/usb/gadget/legacy/printer.c
@@ -1190,6 +1190,9 @@ static int __init printer_bind_config(struct usb_configuration *c)
dev->function.unbind = printer_func_unbind;
dev->function.set_alt = printer_func_set_alt;
dev->function.disable = printer_func_disable;
+ INIT_LIST_HEAD(&dev->tx_reqs);
+ INIT_LIST_HEAD(&dev->rx_reqs);
+ INIT_LIST_HEAD(&dev->rx_buffers);
status = usb_add_function(c, &dev->function);
if (status)
@@ -1233,11 +1236,8 @@ static int __init printer_bind_config(struct usb_configuration *c)
spin_lock_init(&dev->lock);
mutex_init(&dev->lock_printer_io);
- INIT_LIST_HEAD(&dev->tx_reqs);
INIT_LIST_HEAD(&dev->tx_reqs_active);
- INIT_LIST_HEAD(&dev->rx_reqs);
INIT_LIST_HEAD(&dev->rx_reqs_active);
- INIT_LIST_HEAD(&dev->rx_buffers);
init_waitqueue_head(&dev->rx_wait);
init_waitqueue_head(&dev->tx_wait);
init_waitqueue_head(&dev->tx_flush_wait);
OpenPOWER on IntegriCloud