]> err.no Git - linux-2.6/blobdiff - fs/inotify.c
[PATCH] inotify: exit path cleanups
[linux-2.6] / fs / inotify.c
index a87926584cd284c9aa1d94230cc2a659dc2d86db..d41c53c8dfd03e5c67a525afc28ba44e16309912 100644 (file)
@@ -865,23 +865,21 @@ asmlinkage long sys_inotify_init(void)
 
        filp = get_empty_filp();
        if (!filp) {
-               put_unused_fd(fd);
                ret = -ENFILE;
-               goto out;
+               goto out_put_fd;
        }
 
        user = get_uid(current->user);
-
        if (unlikely(atomic_read(&user->inotify_devs) >=
                        inotify_max_user_instances)) {
                ret = -EMFILE;
-               goto out_err;
+               goto out_free_uid;
        }
 
        dev = kmalloc(sizeof(struct inotify_device), GFP_KERNEL);
        if (unlikely(!dev)) {
                ret = -ENOMEM;
-               goto out_err;
+               goto out_free_uid;
        }
 
        filp->f_op = &inotify_fops;
@@ -908,11 +906,11 @@ asmlinkage long sys_inotify_init(void)
        fd_install(fd, filp);
 
        return fd;
-out_err:
-       put_unused_fd (fd);
-       put_filp (filp);
+out_free_uid:
        free_uid(user);
-out:
+       put_filp(filp);
+out_put_fd:
+       put_unused_fd(fd);
        return ret;
 }
 
@@ -923,12 +921,18 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
        struct inotify_device *dev;
        struct nameidata nd;
        struct file *filp;
-       int ret;
+       int ret, fput_needed;
 
-       filp = fget(fd);
-       if (!filp)
+       filp = fget_light(fd, &fput_needed);
+       if (unlikely(!filp))
                return -EBADF;
 
+       /* verify that this is indeed an inotify instance */
+       if (unlikely(filp->f_op != &inotify_fops)) {
+               ret = -EINVAL;
+               goto fput_and_out;
+       }
+
        ret = find_inode(path, &nd);
        if (unlikely(ret))
                goto fput_and_out;
@@ -969,11 +973,11 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
        list_add(&watch->i_list, &inode->inotify_watches);
        ret = watch->wd;
 out:
-       path_release (&nd);
        up(&dev->sem);
        up(&inode->inotify_sem);
+       path_release(&nd);
 fput_and_out:
-       fput(filp);
+       fput_light(filp, fput_needed);
        return ret;
 }
 
@@ -981,15 +985,23 @@ asmlinkage long sys_inotify_rm_watch(int fd, u32 wd)
 {
        struct file *filp;
        struct inotify_device *dev;
-       int ret;
+       int ret, fput_needed;
 
-       filp = fget(fd);
-       if (!filp)
+       filp = fget_light(fd, &fput_needed);
+       if (unlikely(!filp))
                return -EBADF;
+
+       /* verify that this is indeed an inotify instance */
+       if (unlikely(filp->f_op != &inotify_fops)) {
+               ret = -EINVAL;
+               goto out;
+       }
+
        dev = filp->private_data;
        ret = inotify_ignore(dev, wd);
-       fput(filp);
 
+out:
+       fput_light(filp, fput_needed);
        return ret;
 }