usb: gadget: printer: eliminate random pointer dereference
authorAndrzej Pietrasiewicz <andrzej.p@samsung.com>
Tue, 3 Mar 2015 09:52:07 +0000 (10:52 +0100)
committerFelipe Balbi <balbi@ti.com>
Tue, 10 Mar 2015 20:33:34 +0000 (15:33 -0500)
commitc69b8186945c10d245586e9f9703486e9574170c
tree80efc8e1166f18f7972b82c8600d7af7450682bc
parent050f571264154b2f5b4c3c4c1581ab365064ff28
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>
drivers/usb/gadget/legacy/printer.c