| From 67b0503db9c29b04eadfeede6bebbfe5ddad94ef Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?Stefan=20Br=C3=BCns?= <stefan.bruens@rwth-aachen.de> |
| Date: Sun, 12 Feb 2017 13:02:13 -0200 |
| Subject: [media] dvb-usb-firmware: don't do DMA on stack |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Stefan Brüns <stefan.bruens@rwth-aachen.de> |
| |
| commit 67b0503db9c29b04eadfeede6bebbfe5ddad94ef upstream. |
| |
| The buffer allocation for the firmware data was changed in |
| commit 43fab9793c1f ("[media] dvb-usb: don't use stack for firmware load") |
| but the same applies for the reset value. |
| |
| Fixes: 43fab9793c1f ("[media] dvb-usb: don't use stack for firmware load") |
| Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de> |
| Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> |
| Cc: Ben Hutchings <ben@decadent.org.uk> |
| Cc: Brad Spengler <spender@grsecurity.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/media/usb/dvb-usb/dvb-usb-firmware.c | 22 ++++++++++++---------- |
| 1 file changed, 12 insertions(+), 10 deletions(-) |
| |
| --- a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c |
| +++ b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c |
| @@ -36,16 +36,18 @@ static int usb_cypress_writemem(struct u |
| int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type) |
| { |
| struct hexline *hx; |
| - u8 reset; |
| - int ret,pos=0; |
| + u8 *buf; |
| + int ret, pos = 0; |
| + u16 cpu_cs_register = cypress[type].cpu_cs_register; |
| |
| - hx = kmalloc(sizeof(*hx), GFP_KERNEL); |
| - if (!hx) |
| + buf = kmalloc(sizeof(*hx), GFP_KERNEL); |
| + if (!buf) |
| return -ENOMEM; |
| + hx = (struct hexline *)buf; |
| |
| /* stop the CPU */ |
| - reset = 1; |
| - if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1) |
| + buf[0] = 1; |
| + if (usb_cypress_writemem(udev, cpu_cs_register, buf, 1) != 1) |
| err("could not stop the USB controller CPU."); |
| |
| while ((ret = dvb_usb_get_hexline(fw, hx, &pos)) > 0) { |
| @@ -62,21 +64,21 @@ int usb_cypress_load_firmware(struct usb |
| } |
| if (ret < 0) { |
| err("firmware download failed at %d with %d",pos,ret); |
| - kfree(hx); |
| + kfree(buf); |
| return ret; |
| } |
| |
| if (ret == 0) { |
| /* restart the CPU */ |
| - reset = 0; |
| - if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) { |
| + buf[0] = 0; |
| + if (usb_cypress_writemem(udev, cpu_cs_register, buf, 1) != 1) { |
| err("could not restart the USB controller CPU."); |
| ret = -EINVAL; |
| } |
| } else |
| ret = -EIO; |
| |
| - kfree(hx); |
| + kfree(buf); |
| |
| return ret; |
| } |