Message ID | 20200420135147.21572-1-agruenba@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | nfs: Fix potential posix_acl refcnt leak in nfs3_set_acl | expand |
On Mon, 2020-04-20 at 15:51 +0200, Andreas Gruenbacher wrote: > nfs3_set_acl keeps track of the acl it allocated locally to determine > if an acl > needs to be released at the end. This results in a memory leak when > the > function allocates an acl as well as a default acl. Fix by releasing > acls > that differ from the acl originally passed into nfs3_set_acl. > > Fixes: b7fa0554cf1b ("[PATCH] NFS: Add support for NFSv3 ACLs") > Reported-by: Xiyu Yang <xiyuyang19@fudan.edu.cn> > Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> > --- > fs/nfs/nfs3acl.c | 22 +++++++++++++++------- > 1 file changed, 15 insertions(+), 7 deletions(-) > > diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c > index c5c3fc6e6c60..26c94b32d6f4 100644 > --- a/fs/nfs/nfs3acl.c > +++ b/fs/nfs/nfs3acl.c > @@ -253,37 +253,45 @@ int nfs3_proc_setacls(struct inode *inode, > struct posix_acl *acl, > > int nfs3_set_acl(struct inode *inode, struct posix_acl *acl, int > type) > { > - struct posix_acl *alloc = NULL, *dfacl = NULL; > + struct posix_acl *orig = acl, *dfacl = NULL, *alloc; > int status; > > if (S_ISDIR(inode->i_mode)) { > switch(type) { > case ACL_TYPE_ACCESS: > - alloc = dfacl = get_acl(inode, > ACL_TYPE_DEFAULT); > + alloc = get_acl(inode, ACL_TYPE_DEFAULT); > if (IS_ERR(alloc)) > goto fail; > + dfacl = alloc; > break; > > case ACL_TYPE_DEFAULT: > - dfacl = acl; > - alloc = acl = get_acl(inode, ACL_TYPE_ACCESS); > + alloc = get_acl(inode, ACL_TYPE_ACCESS); > if (IS_ERR(alloc)) > goto fail; > + dfacl = acl; > + acl = alloc; > break; > } > } > > if (acl == NULL) { > - alloc = acl = posix_acl_from_mode(inode->i_mode, > GFP_KERNEL); > + alloc = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); > if (IS_ERR(alloc)) > goto fail; > + acl = alloc; > } > status = __nfs3_proc_setacls(inode, acl, dfacl); > - posix_acl_release(alloc); > +out: > + if (acl != orig) > + posix_acl_release(acl); > + if (dfacl != orig) > + posix_acl_release(dfacl); > return status; > > fail: > - return PTR_ERR(alloc); > + status = PTR_ERR(alloc); > + goto out; > } > > const struct xattr_handler *nfs3_xattr_handlers[] = { > > base-commit: ae83d0b416db002fe95601e7f97f64b59514d936 Thanks Andreas! This one looks good.
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c index c5c3fc6e6c60..26c94b32d6f4 100644 --- a/fs/nfs/nfs3acl.c +++ b/fs/nfs/nfs3acl.c @@ -253,37 +253,45 @@ int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, int nfs3_set_acl(struct inode *inode, struct posix_acl *acl, int type) { - struct posix_acl *alloc = NULL, *dfacl = NULL; + struct posix_acl *orig = acl, *dfacl = NULL, *alloc; int status; if (S_ISDIR(inode->i_mode)) { switch(type) { case ACL_TYPE_ACCESS: - alloc = dfacl = get_acl(inode, ACL_TYPE_DEFAULT); + alloc = get_acl(inode, ACL_TYPE_DEFAULT); if (IS_ERR(alloc)) goto fail; + dfacl = alloc; break; case ACL_TYPE_DEFAULT: - dfacl = acl; - alloc = acl = get_acl(inode, ACL_TYPE_ACCESS); + alloc = get_acl(inode, ACL_TYPE_ACCESS); if (IS_ERR(alloc)) goto fail; + dfacl = acl; + acl = alloc; break; } } if (acl == NULL) { - alloc = acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); + alloc = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); if (IS_ERR(alloc)) goto fail; + acl = alloc; } status = __nfs3_proc_setacls(inode, acl, dfacl); - posix_acl_release(alloc); +out: + if (acl != orig) + posix_acl_release(acl); + if (dfacl != orig) + posix_acl_release(dfacl); return status; fail: - return PTR_ERR(alloc); + status = PTR_ERR(alloc); + goto out; } const struct xattr_handler *nfs3_xattr_handlers[] = {
nfs3_set_acl keeps track of the acl it allocated locally to determine if an acl needs to be released at the end. This results in a memory leak when the function allocates an acl as well as a default acl. Fix by releasing acls that differ from the acl originally passed into nfs3_set_acl. Fixes: b7fa0554cf1b ("[PATCH] NFS: Add support for NFSv3 ACLs") Reported-by: Xiyu Yang <xiyuyang19@fudan.edu.cn> Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> --- fs/nfs/nfs3acl.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) base-commit: ae83d0b416db002fe95601e7f97f64b59514d936