[media] marvell-ccic: check register address
authorHans Verkuil <hans.verkuil@cisco.com>
Wed, 29 May 2013 10:00:02 +0000 (07:00 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Mon, 17 Jun 2013 11:54:44 +0000 (08:54 -0300)
Prevent out-of-range register accesses.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/platform/marvell-ccic/cafe-driver.c
drivers/media/platform/marvell-ccic/mcam-core.c
drivers/media/platform/marvell-ccic/mcam-core.h
drivers/media/platform/marvell-ccic/mmp-driver.c

index 7b07fc55cd3c1a10c3bbc17ff4a0e82766e1396c..1f079ff33d4b94f7e0bcd92edc2f17504952fe6b 100644 (file)
@@ -500,6 +500,7 @@ static int cafe_pci_probe(struct pci_dev *pdev,
                printk(KERN_ERR "Unable to ioremap cafe-ccic regs\n");
                goto out_disable;
        }
+       mcam->regs_size = pci_resource_len(pdev, 0);
        ret = request_irq(pdev->irq, cafe_irq, IRQF_SHARED, "cafe-ccic", cam);
        if (ret)
                goto out_iounmap;
index a187161e980ecf818cba4e8234a21cb0f997d468..c69cfc4413fcb087170b896e875c6a84515bf550 100644 (file)
@@ -1404,6 +1404,8 @@ static int mcam_vidioc_g_register(struct file *file, void *priv,
 {
        struct mcam_camera *cam = priv;
 
+       if (reg->reg > cam->regs_size - 4)
+               return -EINVAL;
        reg->val = mcam_reg_read(cam, reg->reg);
        reg->size = 4;
        return 0;
@@ -1414,6 +1416,8 @@ static int mcam_vidioc_s_register(struct file *file, void *priv,
 {
        struct mcam_camera *cam = priv;
 
+       if (reg->reg > cam->regs_size - 4)
+               return -EINVAL;
        mcam_reg_write(cam, reg->reg, reg->val);
        return 0;
 }
index 46b6ea31e66b9a84b7602f5f37902778c93882cf..520c8ded9443f5869e101f8ca92d3c3346e9894f 100644 (file)
@@ -101,6 +101,7 @@ struct mcam_camera {
         */
        struct i2c_adapter *i2c_adapter;
        unsigned char __iomem *regs;
+       unsigned regs_size; /* size in bytes of the register space */
        spinlock_t dev_lock;
        struct device *dev; /* For messages, dma alloc */
        enum mcam_chip_id chip_id;
index cadad647ce0e0ed70a76c0d24aa1c883d06ee8c3..a634888271cd7a38ff162bc56d4b97b88923e09f 100644 (file)
@@ -202,6 +202,7 @@ static int mmpcam_probe(struct platform_device *pdev)
                ret = -ENODEV;
                goto out_free;
        }
+       mcam->regs_size = resource_size(res);
        /*
         * Power/clock memory is elsewhere; get it too.  Perhaps this
         * should really be managed outside of this driver?