diff options
| -rw-r--r-- | fs/nfsd/nfs4acl.c | 50 |
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 | |||
| 521 | static 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 | |||
| 532 | static struct posix_acl * | 502 | static struct posix_acl * |
| 533 | posix_state_to_acl(struct posix_acl_state *state, unsigned int flags) | 503 | posix_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; |
| 614 | out_err: | ||
| 615 | posix_acl_release(pacl); | ||
| 616 | return ERR_PTR(error); | ||
| 617 | } | 569 | } |
| 618 | 570 | ||
| 619 | static inline void allow_bits(struct posix_ace_state *astate, u32 mask) | 571 | static inline void allow_bits(struct posix_ace_state *astate, u32 mask) |
