aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2015-03-26 10:37:51 -0400
committerJ. Bruce Fields <bfields@redhat.com>2015-03-31 16:46:39 -0400
commitb14f4f7e61aaa4437a42e2e11055fc01782a15bf (patch)
tree8dc8c6b08a6948f3e400257cbe23377c1960d10e /fs/nfsd
parent629b8729cc2ca8fde7deb008dab09f3ad19fed52 (diff)
nfsd: allow setting acls with unenforceable DENYs
We've been refusing ACLs that DENY permissions that we can't effectively deny. (For example, we can't deny permission to read attributes.) Andreas points out that any DENY of Window's "read", "write", or "modify" permissions would trigger this. That would be annoying. So maybe we should be a little less paranoid, and ignore entirely the permissions that are meaningless to us. Reported-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfs4acl.c50
1 files changed, 1 insertions, 49 deletions
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c
index 59fd76651781..eaf4605a4b9e 100644
--- a/fs/nfsd/nfs4acl.c
+++ b/fs/nfsd/nfs4acl.c
@@ -499,43 +499,13 @@ static inline void add_to_mask(struct posix_acl_state *state, struct posix_ace_s
499 state->mask.allow |= astate->allow; 499 state->mask.allow |= astate->allow;
500} 500}
501 501
502/*
503 * Certain bits (SYNCHRONIZE, DELETE, WRITE_OWNER, READ/WRITE_NAMED_ATTRS,
504 * READ_ATTRIBUTES, READ_ACL) are currently unenforceable and don't translate
505 * to traditional read/write/execute permissions.
506 *
507 * It's problematic to reject acls that use certain mode bits, because it
508 * places the burden on users to learn the rules about which bits one
509 * particular server sets, without giving the user a lot of help--we return an
510 * error that could mean any number of different things. To make matters
511 * worse, the problematic bits might be introduced by some application that's
512 * automatically mapping from some other acl model.
513 *
514 * So wherever possible we accept anything, possibly erring on the side of
515 * denying more permissions than necessary.
516 *
517 * However we do reject *explicit* DENY's of a few bits representing
518 * permissions we could never deny:
519 */
520
521static inline int check_deny(u32 mask, int isowner)
522{
523 if (mask & (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL))
524 return -EINVAL;
525 if (!isowner)
526 return 0;
527 if (mask & (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL))
528 return -EINVAL;
529 return 0;
530}
531
532static struct posix_acl * 502static struct posix_acl *
533posix_state_to_acl(struct posix_acl_state *state, unsigned int flags) 503posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
534{ 504{
535 struct posix_acl_entry *pace; 505 struct posix_acl_entry *pace;
536 struct posix_acl *pacl; 506 struct posix_acl *pacl;
537 int nace; 507 int nace;
538 int i, error = 0; 508 int i;
539 509
540 /* 510 /*
541 * ACLs with no ACEs are treated differently in the inheritable 511 * ACLs with no ACEs are treated differently in the inheritable
@@ -560,17 +530,11 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
560 530
561 pace = pacl->a_entries; 531 pace = pacl->a_entries;
562 pace->e_tag = ACL_USER_OBJ; 532 pace->e_tag = ACL_USER_OBJ;
563 error = check_deny(state->owner.deny, 1);
564 if (error)
565 goto out_err;
566 low_mode_from_nfs4(state->owner.allow, &pace->e_perm, flags); 533 low_mode_from_nfs4(state->owner.allow, &pace->e_perm, flags);
567 534
568 for (i=0; i < state->users->n; i++) { 535 for (i=0; i < state->users->n; i++) {
569 pace++; 536 pace++;
570 pace->e_tag = ACL_USER; 537 pace->e_tag = ACL_USER;
571 error = check_deny(state->users->aces[i].perms.deny, 0);
572 if (error)
573 goto out_err;
574 low_mode_from_nfs4(state->users->aces[i].perms.allow, 538 low_mode_from_nfs4(state->users->aces[i].perms.allow,
575 &pace->e_perm, flags); 539 &pace->e_perm, flags);
576 pace->e_uid = state->users->aces[i].uid; 540 pace->e_uid = state->users->aces[i].uid;
@@ -579,18 +543,12 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
579 543
580 pace++; 544 pace++;
581 pace->e_tag = ACL_GROUP_OBJ; 545 pace->e_tag = ACL_GROUP_OBJ;
582 error = check_deny(state->group.deny, 0);
583 if (error)
584 goto out_err;
585 low_mode_from_nfs4(state->group.allow, &pace->e_perm, flags); 546 low_mode_from_nfs4(state->group.allow, &pace->e_perm, flags);
586 add_to_mask(state, &state->group); 547 add_to_mask(state, &state->group);
587 548
588 for (i=0; i < state->groups->n; i++) { 549 for (i=0; i < state->groups->n; i++) {
589 pace++; 550 pace++;
590 pace->e_tag = ACL_GROUP; 551 pace->e_tag = ACL_GROUP;
591 error = check_deny(state->groups->aces[i].perms.deny, 0);
592 if (error)
593 goto out_err;
594 low_mode_from_nfs4(state->groups->aces[i].perms.allow, 552 low_mode_from_nfs4(state->groups->aces[i].perms.allow,
595 &pace->e_perm, flags); 553 &pace->e_perm, flags);
596 pace->e_gid = state->groups->aces[i].gid; 554 pace->e_gid = state->groups->aces[i].gid;
@@ -605,15 +563,9 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
605 563
606 pace++; 564 pace++;
607 pace->e_tag = ACL_OTHER; 565 pace->e_tag = ACL_OTHER;
608 error = check_deny(state->other.deny, 0);
609 if (error)
610 goto out_err;
611 low_mode_from_nfs4(state->other.allow, &pace->e_perm, flags); 566 low_mode_from_nfs4(state->other.allow, &pace->e_perm, flags);
612 567
613 return pacl; 568 return pacl;
614out_err:
615 posix_acl_release(pacl);
616 return ERR_PTR(error);
617} 569}
618 570
619static inline void allow_bits(struct posix_ace_state *astate, u32 mask) 571static inline void allow_bits(struct posix_ace_state *astate, u32 mask)