knfsd: nfsd4: fix handling of acl errrors
nfs4_acl_nfsv4_to_posix() returns an error and returns any posix acls calculated in two caller-provided pointers. It was setting these pointers to -errno in some error cases, resulting in nfsd4_set_nfs4_acl() calling posix_acl_release() with a -errno as an argument. Fix both the caller and the callee, by modifying nfsd4_set_nfs4_acl() to stop relying on the passed-in-pointers being left as NULL in the error case, and by modifying nfs4_acl_nfsv4_to_posix() to stop returning garbage in those pointers. Thanks to Alex Soule for reporting the bug. Signed-off-by: "J. Bruce Fields" <bfields@citi.umich.edu> Cc: Alexander Soule <soule@umich.edu> Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
0ac68d1799
commit
4b2ca38ad6
2 changed files with 10 additions and 15 deletions
|
@ -737,13 +737,16 @@ int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, struct posix_acl **pacl,
|
|||
*pacl = posix_state_to_acl(&effective_acl_state, flags);
|
||||
if (IS_ERR(*pacl)) {
|
||||
ret = PTR_ERR(*pacl);
|
||||
*pacl = NULL;
|
||||
goto out_dstate;
|
||||
}
|
||||
*dpacl = posix_state_to_acl(&default_acl_state,
|
||||
flags | NFS4_ACL_TYPE_DEFAULT);
|
||||
if (IS_ERR(*dpacl)) {
|
||||
ret = PTR_ERR(*dpacl);
|
||||
*dpacl = NULL;
|
||||
posix_acl_release(*pacl);
|
||||
*pacl = NULL;
|
||||
goto out_dstate;
|
||||
}
|
||||
sort_pacl(*pacl);
|
||||
|
|
|
@ -435,7 +435,7 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
|
|||
/* Get inode */
|
||||
error = fh_verify(rqstp, fhp, 0 /* S_IFREG */, MAY_SATTR);
|
||||
if (error)
|
||||
goto out;
|
||||
return error;
|
||||
|
||||
dentry = fhp->fh_dentry;
|
||||
inode = dentry->d_inode;
|
||||
|
@ -444,33 +444,25 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
|
|||
|
||||
host_error = nfs4_acl_nfsv4_to_posix(acl, &pacl, &dpacl, flags);
|
||||
if (host_error == -EINVAL) {
|
||||
error = nfserr_attrnotsupp;
|
||||
goto out;
|
||||
return nfserr_attrnotsupp;
|
||||
} else if (host_error < 0)
|
||||
goto out_nfserr;
|
||||
|
||||
host_error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS);
|
||||
if (host_error < 0)
|
||||
goto out_nfserr;
|
||||
goto out_release;
|
||||
|
||||
if (S_ISDIR(inode->i_mode)) {
|
||||
if (S_ISDIR(inode->i_mode))
|
||||
host_error = set_nfsv4_acl_one(dentry, dpacl, POSIX_ACL_XATTR_DEFAULT);
|
||||
if (host_error < 0)
|
||||
goto out_nfserr;
|
||||
}
|
||||
|
||||
error = nfs_ok;
|
||||
|
||||
out:
|
||||
out_release:
|
||||
posix_acl_release(pacl);
|
||||
posix_acl_release(dpacl);
|
||||
return (error);
|
||||
out_nfserr:
|
||||
if (host_error == -EOPNOTSUPP)
|
||||
error = nfserr_attrnotsupp;
|
||||
return nfserr_attrnotsupp;
|
||||
else
|
||||
error = nfserrno(host_error);
|
||||
goto out;
|
||||
return nfserrno(host_error);
|
||||
}
|
||||
|
||||
static struct posix_acl *
|
||||
|
|
Loading…
Reference in a new issue