[media] lirc_dev: more error-checking improvements
authorJarod Wilson <jarod@redhat.com>
Mon, 18 Oct 2010 15:02:01 +0000 (12:02 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Fri, 22 Oct 2010 22:05:36 +0000 (20:05 -0200)
Signed-off-by: Jarod Wilson <jarod@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/IR/lirc_dev.c

index 3eea373..e3dbf12 100644 (file)
@@ -74,8 +74,6 @@ static struct class *lirc_class;
  */
 static void lirc_irctl_init(struct irctl *ir)
 {
-       dev_dbg(ir->d.dev, LOGHEAD "initializing irctl\n",
-               ir->d.name, ir->d.minor);
        mutex_init(&ir->irctl_lock);
        ir->d.minor = NOPLUG;
 }
@@ -205,6 +203,12 @@ int lirc_register_driver(struct lirc_driver *d)
                goto out;
        }
 
+       if (!d->dev) {
+               printk(KERN_ERR "%s: dev pointer not filled in!\n", __func__);
+               err = -EINVAL;
+               goto out;
+       }
+
        if (MAX_IRCTL_DEVICES <= d->minor) {
                dev_err(d->dev, "lirc_dev: lirc_register_driver: "
                        "\"minor\" must be between 0 and %d (%d)!\n",
@@ -319,7 +323,6 @@ int lirc_register_driver(struct lirc_driver *d)
                d->features = LIRC_CAN_REC_LIRCCODE;
 
        ir->d = *d;
-       ir->d.minor = minor;
 
        device_create(lirc_class, ir->d.dev,
                      MKDEV(MAJOR(lirc_base_dev), ir->d.minor), NULL,
@@ -474,11 +477,16 @@ int lirc_dev_fop_close(struct inode *inode, struct file *file)
 {
        struct irctl *ir = irctls[iminor(inode)];
 
+       if (!ir) {
+               printk(KERN_ERR "%s: called with invalid irctl\n", __func__);
+               return -EINVAL;
+       }
+
        dev_dbg(ir->d.dev, LOGHEAD "close called\n", ir->d.name, ir->d.minor);
 
        WARN_ON(mutex_lock_killable(&lirc_dev_lock));
 
-       --ir->open;
+       ir->open--;
        if (ir->attached) {
                ir->d.set_use_dec(ir->d.data);
                module_put(ir->cdev.owner);
@@ -499,6 +507,11 @@ unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait)
        struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
        unsigned int ret;
 
+       if (!ir) {
+               printk(KERN_ERR "%s: called with invalid irctl\n", __func__);
+               return POLLERR;
+       }
+
        dev_dbg(ir->d.dev, LOGHEAD "poll called\n", ir->d.name, ir->d.minor);
 
        if (!ir->attached) {
@@ -613,12 +626,21 @@ ssize_t lirc_dev_fop_read(struct file *file,
                          loff_t *ppos)
 {
        struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
-       unsigned char buf[ir->chunk_size];
+       unsigned char *buf;
        int ret = 0, written = 0;
        DECLARE_WAITQUEUE(wait, current);
 
+       if (!ir) {
+               printk(KERN_ERR "%s: called with invalid irctl\n", __func__);
+               return -ENODEV;
+       }
+
        dev_dbg(ir->d.dev, LOGHEAD "read called\n", ir->d.name, ir->d.minor);
 
+       buf = kzalloc(ir->chunk_size, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
        if (mutex_lock_interruptible(&ir->irctl_lock))
                return -ERESTARTSYS;
        if (!ir->attached) {
@@ -690,6 +712,7 @@ ssize_t lirc_dev_fop_read(struct file *file,
        mutex_unlock(&ir->irctl_lock);
 
 out_unlocked:
+       kfree(buf);
        dev_dbg(ir->d.dev, LOGHEAD "read result = %s (%d)\n",
                ir->d.name, ir->d.minor, ret ? "-EFAULT" : "OK", ret);
 
@@ -718,6 +741,11 @@ ssize_t lirc_dev_fop_write(struct file *file, const char *buffer,
 {
        struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
 
+       if (!ir) {
+               printk(KERN_ERR "%s: called with invalid irctl\n", __func__);
+               return -ENODEV;
+       }
+
        dev_dbg(ir->d.dev, LOGHEAD "write called\n", ir->d.name, ir->d.minor);
 
        if (!ir->attached)