aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@fieldses.org>2007-07-17 07:04:37 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-17 13:23:07 -0400
commit4b2ca38ad6c44ed0442092a829e6e954bf3580af (patch)
treed3256d5a1e2a0276326f8abb2e6aabc3df3812da /fs
parent0ac68d17996eb421dde51452b89d5545ba07c6fe (diff)
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>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfsd/nfs4acl.c3
-rw-r--r--fs/nfsd/vfs.c22
2 files changed, 10 insertions, 15 deletions
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c
index 4adb5ee4759b..b6ed38380ab8 100644
--- a/fs/nfsd/nfs4acl.c
+++ b/fs/nfsd/nfs4acl.c
@@ -737,13 +737,16 @@ int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, struct posix_acl **pacl,
737 *pacl = posix_state_to_acl(&effective_acl_state, flags); 737 *pacl = posix_state_to_acl(&effective_acl_state, flags);
738 if (IS_ERR(*pacl)) { 738 if (IS_ERR(*pacl)) {
739 ret = PTR_ERR(*pacl); 739 ret = PTR_ERR(*pacl);
740 *pacl = NULL;
740 goto out_dstate; 741 goto out_dstate;
741 } 742 }
742 *dpacl = posix_state_to_acl(&default_acl_state, 743 *dpacl = posix_state_to_acl(&default_acl_state,
743 flags | NFS4_ACL_TYPE_DEFAULT); 744 flags | NFS4_ACL_TYPE_DEFAULT);
744 if (IS_ERR(*dpacl)) { 745 if (IS_ERR(*dpacl)) {
745 ret = PTR_ERR(*dpacl); 746 ret = PTR_ERR(*dpacl);
747 *dpacl = NULL;
746 posix_acl_release(*pacl); 748 posix_acl_release(*pacl);
749 *pacl = NULL;
747 goto out_dstate; 750 goto out_dstate;
748 } 751 }
749 sort_pacl(*pacl); 752 sort_pacl(*pacl);
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 945b1cedde2b..8d6b5c483ae1 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -435,7 +435,7 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
435 /* Get inode */ 435 /* Get inode */
436 error = fh_verify(rqstp, fhp, 0 /* S_IFREG */, MAY_SATTR); 436 error = fh_verify(rqstp, fhp, 0 /* S_IFREG */, MAY_SATTR);
437 if (error) 437 if (error)
438 goto out; 438 return error;
439 439
440 dentry = fhp->fh_dentry; 440 dentry = fhp->fh_dentry;
441 inode = dentry->d_inode; 441 inode = dentry->d_inode;
@@ -444,33 +444,25 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
444 444
445 host_error = nfs4_acl_nfsv4_to_posix(acl, &pacl, &dpacl, flags); 445 host_error = nfs4_acl_nfsv4_to_posix(acl, &pacl, &dpacl, flags);
446 if (host_error == -EINVAL) { 446 if (host_error == -EINVAL) {
447 error = nfserr_attrnotsupp; 447 return nfserr_attrnotsupp;
448 goto out;
449 } else if (host_error < 0) 448 } else if (host_error < 0)
450 goto out_nfserr; 449 goto out_nfserr;
451 450
452 host_error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS); 451 host_error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS);
453 if (host_error < 0) 452 if (host_error < 0)
454 goto out_nfserr; 453 goto out_release;
455 454
456 if (S_ISDIR(inode->i_mode)) { 455 if (S_ISDIR(inode->i_mode))
457 host_error = set_nfsv4_acl_one(dentry, dpacl, POSIX_ACL_XATTR_DEFAULT); 456 host_error = set_nfsv4_acl_one(dentry, dpacl, POSIX_ACL_XATTR_DEFAULT);
458 if (host_error < 0)
459 goto out_nfserr;
460 }
461
462 error = nfs_ok;
463 457
464out: 458out_release:
465 posix_acl_release(pacl); 459 posix_acl_release(pacl);
466 posix_acl_release(dpacl); 460 posix_acl_release(dpacl);
467 return (error);
468out_nfserr: 461out_nfserr:
469 if (host_error == -EOPNOTSUPP) 462 if (host_error == -EOPNOTSUPP)
470 error = nfserr_attrnotsupp; 463 return nfserr_attrnotsupp;
471 else 464 else
472 error = nfserrno(host_error); 465 return nfserrno(host_error);
473 goto out;
474} 466}
475 467
476static struct posix_acl * 468static struct posix_acl *