]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
9p: close ACL leaks
authorAl Viro <viro@zeniv.linux.org.uk>
Sat, 23 Jul 2011 06:28:13 +0000 (02:28 -0400)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 3 Oct 2011 18:40:19 +0000 (11:40 -0700)
commit 1ec95bf34d976b38897d1977b155a544d77b05e7 upstream.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
fs/9p/acl.c
fs/9p/acl.h
fs/9p/vfs_inode_dotl.c

index 535ab6eccb1a8de6090ff94448a3bf044d1b6514..4a866cd06287b240e4c9d7b79c183e0822fc83a1 100644 (file)
@@ -185,12 +185,15 @@ int v9fs_acl_chmod(struct dentry *dentry)
 }
 
 int v9fs_set_create_acl(struct dentry *dentry,
-                       struct posix_acl *dpacl, struct posix_acl *pacl)
+                       struct posix_acl **dpacl, struct posix_acl **pacl)
 {
-       v9fs_set_acl(dentry, ACL_TYPE_DEFAULT, dpacl);
-       v9fs_set_acl(dentry, ACL_TYPE_ACCESS, pacl);
-       posix_acl_release(dpacl);
-       posix_acl_release(pacl);
+       if (dentry) {
+               v9fs_set_acl(dentry, ACL_TYPE_DEFAULT, *dpacl);
+               v9fs_set_acl(dentry, ACL_TYPE_ACCESS, *pacl);
+       }
+       posix_acl_release(*dpacl);
+       posix_acl_release(*pacl);
+       *dpacl = *pacl = NULL;
        return 0;
 }
 
@@ -212,11 +215,11 @@ int v9fs_acl_mode(struct inode *dir, mode_t *modep,
                struct posix_acl *clone;
 
                if (S_ISDIR(mode))
-                       *dpacl = acl;
+                       *dpacl = posix_acl_dup(acl);
                clone = posix_acl_clone(acl, GFP_NOFS);
-               retval = -ENOMEM;
+               posix_acl_release(acl);
                if (!clone)
-                       goto cleanup;
+                       return -ENOMEM;
 
                retval = posix_acl_create_masq(clone, &mode);
                if (retval < 0) {
@@ -225,11 +228,12 @@ int v9fs_acl_mode(struct inode *dir, mode_t *modep,
                }
                if (retval > 0)
                        *pacl = clone;
+               else
+                       posix_acl_release(clone);
        }
        *modep  = mode;
        return 0;
 cleanup:
-       posix_acl_release(acl);
        return retval;
 
 }
index 7ef3ac9f6d95ba8b2111929c5340ae63512151a9..c47ea9cf3031a67321071cfbe5afca29cf135f89 100644 (file)
@@ -19,7 +19,7 @@ extern int v9fs_get_acl(struct inode *, struct p9_fid *);
 extern int v9fs_check_acl(struct inode *inode, int mask, unsigned int flags);
 extern int v9fs_acl_chmod(struct dentry *);
 extern int v9fs_set_create_acl(struct dentry *,
-                              struct posix_acl *, struct posix_acl *);
+                              struct posix_acl **, struct posix_acl **);
 extern int v9fs_acl_mode(struct inode *dir, mode_t *modep,
                         struct posix_acl **dpacl, struct posix_acl **pacl);
 #else
@@ -33,8 +33,8 @@ static inline int v9fs_acl_chmod(struct dentry *dentry)
        return 0;
 }
 static inline int v9fs_set_create_acl(struct dentry *dentry,
-                                     struct posix_acl *dpacl,
-                                     struct posix_acl *pacl)
+                                     struct posix_acl **dpacl,
+                                     struct posix_acl **pacl)
 {
        return 0;
 }
index bec75f077ddc7bd09ff0ba60224062929b76f8e0..185ce37ee3fbb880953fa9b929647b2e53de21e2 100644 (file)
@@ -287,7 +287,7 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
                goto error;
 
        /* Now set the ACL based on the default value */
-       v9fs_set_create_acl(dentry, dacl, pacl);
+       v9fs_set_create_acl(dentry, &dacl, &pacl);
 
        v9inode = V9FS_I(inode);
        mutex_lock(&v9inode->v_mutex);
@@ -328,6 +328,7 @@ error:
 err_clunk_old_fid:
        if (ofid)
                p9_client_clunk(ofid);
+       v9fs_set_create_acl(NULL, &dacl, &pacl);
        return err;
 }
 
@@ -421,12 +422,13 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir,
                d_instantiate(dentry, inode);
        }
        /* Now set the ACL based on the default value */
-       v9fs_set_create_acl(dentry, dacl, pacl);
+       v9fs_set_create_acl(dentry, &dacl, &pacl);
        inc_nlink(dir);
        v9fs_invalidate_inode_attr(dir);
 error:
        if (fid)
                p9_client_clunk(fid);
+       v9fs_set_create_acl(NULL, &dacl, &pacl);
        return err;
 }
 
@@ -826,10 +828,11 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode,
                d_instantiate(dentry, inode);
        }
        /* Now set the ACL based on the default value */
-       v9fs_set_create_acl(dentry, dacl, pacl);
+       v9fs_set_create_acl(dentry, &dacl, &pacl);
 error:
        if (fid)
                p9_client_clunk(fid);
+       v9fs_set_create_acl(NULL, &dacl, &pacl);
        return err;
 }