diff options
-rw-r--r-- | security/commoncap.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/security/commoncap.c b/security/commoncap.c index ad7536d76820..5fa839c7fb3f 100644 --- a/security/commoncap.c +++ b/security/commoncap.c | |||
@@ -766,7 +766,7 @@ static inline bool __is_setgid(struct cred *new, const struct cred *old) | |||
766 | { return !gid_eq(new->egid, old->gid); } | 766 | { return !gid_eq(new->egid, old->gid); } |
767 | 767 | ||
768 | /* | 768 | /* |
769 | * Audit candidate if current->cap_effective is set | 769 | * 1) Audit candidate if current->cap_effective is set |
770 | * | 770 | * |
771 | * We do not bother to audit if 3 things are true: | 771 | * We do not bother to audit if 3 things are true: |
772 | * 1) cap_effective has all caps | 772 | * 1) cap_effective has all caps |
@@ -776,16 +776,31 @@ static inline bool __is_setgid(struct cred *new, const struct cred *old) | |||
776 | * | 776 | * |
777 | * Number 1 above might fail if you don't have a full bset, but I think | 777 | * Number 1 above might fail if you don't have a full bset, but I think |
778 | * that is interesting information to audit. | 778 | * that is interesting information to audit. |
779 | * | ||
780 | * A number of other conditions require logging: | ||
781 | * 2) something prevented setuid root getting all caps | ||
782 | * 3) non-setuid root gets fcaps | ||
783 | * 4) non-setuid root gets ambient | ||
779 | */ | 784 | */ |
780 | static inline bool nonroot_raised_pE(struct cred *cred, kuid_t root) | 785 | static inline bool nonroot_raised_pE(struct cred *new, const struct cred *old, |
786 | kuid_t root, bool has_fcap) | ||
781 | { | 787 | { |
782 | bool ret = false; | 788 | bool ret = false; |
783 | 789 | ||
784 | if (__cap_grew(effective, ambient, cred) && | 790 | if ((__cap_grew(effective, ambient, new) && |
785 | !(__cap_full(effective, cred) && | 791 | !(__cap_full(effective, new) && |
786 | (__is_eff(root, cred) || __is_real(root, cred)) && | 792 | (__is_eff(root, new) || __is_real(root, new)) && |
787 | root_privileged())) | 793 | root_privileged())) || |
794 | (root_privileged() && | ||
795 | __is_suid(root, new) && | ||
796 | !__cap_full(effective, new)) || | ||
797 | (!__is_setuid(new, old) && | ||
798 | ((has_fcap && | ||
799 | __cap_gained(permitted, new, old)) || | ||
800 | __cap_gained(ambient, new, old)))) | ||
801 | |||
788 | ret = true; | 802 | ret = true; |
803 | |||
789 | return ret; | 804 | return ret; |
790 | } | 805 | } |
791 | 806 | ||
@@ -865,7 +880,7 @@ int cap_bprm_set_creds(struct linux_binprm *bprm) | |||
865 | if (WARN_ON(!cap_ambient_invariant_ok(new))) | 880 | if (WARN_ON(!cap_ambient_invariant_ok(new))) |
866 | return -EPERM; | 881 | return -EPERM; |
867 | 882 | ||
868 | if (nonroot_raised_pE(new, root_uid)) { | 883 | if (nonroot_raised_pE(new, old, root_uid, has_fcap)) { |
869 | ret = audit_log_bprm_fcaps(bprm, new, old); | 884 | ret = audit_log_bprm_fcaps(bprm, new, old); |
870 | if (ret < 0) | 885 | if (ret < 0) |
871 | return ret; | 886 | return ret; |