Skip to content

Commit 7648f93

Browse files
Andreas GruenbacherTrond Myklebust
authored andcommitted
nfs: Fix potential posix_acl refcnt leak in nfs3_set_acl
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: b7fa055 ("[PATCH] NFS: Add support for NFSv3 ACLs") Reported-by: Xiyu Yang <[email protected]> Signed-off-by: Andreas Gruenbacher <[email protected]> Signed-off-by: Trond Myklebust <[email protected]>
1 parent 4d8948c commit 7648f93

File tree

1 file changed

+15
-7
lines changed

1 file changed

+15
-7
lines changed

fs/nfs/nfs3acl.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -253,37 +253,45 @@ int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
253253

254254
int nfs3_set_acl(struct inode *inode, struct posix_acl *acl, int type)
255255
{
256-
struct posix_acl *alloc = NULL, *dfacl = NULL;
256+
struct posix_acl *orig = acl, *dfacl = NULL, *alloc;
257257
int status;
258258

259259
if (S_ISDIR(inode->i_mode)) {
260260
switch(type) {
261261
case ACL_TYPE_ACCESS:
262-
alloc = dfacl = get_acl(inode, ACL_TYPE_DEFAULT);
262+
alloc = get_acl(inode, ACL_TYPE_DEFAULT);
263263
if (IS_ERR(alloc))
264264
goto fail;
265+
dfacl = alloc;
265266
break;
266267

267268
case ACL_TYPE_DEFAULT:
268-
dfacl = acl;
269-
alloc = acl = get_acl(inode, ACL_TYPE_ACCESS);
269+
alloc = get_acl(inode, ACL_TYPE_ACCESS);
270270
if (IS_ERR(alloc))
271271
goto fail;
272+
dfacl = acl;
273+
acl = alloc;
272274
break;
273275
}
274276
}
275277

276278
if (acl == NULL) {
277-
alloc = acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
279+
alloc = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
278280
if (IS_ERR(alloc))
279281
goto fail;
282+
acl = alloc;
280283
}
281284
status = __nfs3_proc_setacls(inode, acl, dfacl);
282-
posix_acl_release(alloc);
285+
out:
286+
if (acl != orig)
287+
posix_acl_release(acl);
288+
if (dfacl != orig)
289+
posix_acl_release(dfacl);
283290
return status;
284291

285292
fail:
286-
return PTR_ERR(alloc);
293+
status = PTR_ERR(alloc);
294+
goto out;
287295
}
288296

289297
const struct xattr_handler *nfs3_xattr_handlers[] = {

0 commit comments

Comments
 (0)