media: airspy: respect the DMA coherency rules
authorOliver Neukum <oneukum@suse.com>
Wed, 18 May 2022 08:10:45 +0000 (09:10 +0100)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Mon, 20 Jun 2022 09:30:34 +0000 (10:30 +0100)
If we want to avoid memory corruption
on incoherent architectures, buffers for DMA
must not reside
- on the stack
- embedded within other structures

Allocate them separately.

v2: fix uninitialized return value

Signed-off-by: Oliver Neukum <oneukum@suse.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
drivers/media/usb/airspy/airspy.c

index d568452..240a7cc 100644 (file)
@@ -123,7 +123,7 @@ struct airspy {
 
        /* USB control message buffer */
        #define BUF_SIZE 128
-       u8 buf[BUF_SIZE];
+       u8 *buf;
 
        /* Current configuration */
        unsigned int f_adc;
@@ -856,6 +856,7 @@ static void airspy_video_release(struct v4l2_device *v)
 
        v4l2_ctrl_handler_free(&s->hdl);
        v4l2_device_unregister(&s->v4l2_dev);
+       kfree(s->buf);
        kfree(s);
 }
 
@@ -963,7 +964,10 @@ static int airspy_probe(struct usb_interface *intf,
 {
        struct airspy *s;
        int ret;
-       u8 u8tmp, buf[BUF_SIZE];
+       u8 u8tmp, *buf;
+
+       buf = NULL;
+       ret = -ENOMEM;
 
        s = kzalloc(sizeof(struct airspy), GFP_KERNEL);
        if (s == NULL) {
@@ -971,6 +975,13 @@ static int airspy_probe(struct usb_interface *intf,
                return -ENOMEM;
        }
 
+       s->buf = kzalloc(BUF_SIZE, GFP_KERNEL);
+       if (!s->buf)
+               goto err_free_mem;
+       buf = kzalloc(BUF_SIZE, GFP_KERNEL);
+       if (!buf)
+               goto err_free_mem;
+
        mutex_init(&s->v4l2_lock);
        mutex_init(&s->vb_queue_lock);
        spin_lock_init(&s->queued_bufs_lock);
@@ -1068,6 +1079,8 @@ err_free_controls:
        v4l2_ctrl_handler_free(&s->hdl);
        v4l2_device_unregister(&s->v4l2_dev);
 err_free_mem:
+       kfree(buf);
+       kfree(s->buf);
        kfree(s);
        return ret;
 }