[PATCH V4 10/10] capabilities: audit log other surprising conditions
Paul Moore
paul at paul-moore.com
Wed Sep 20 22:22:30 UTC 2017
On Tue, Sep 5, 2017 at 2:46 AM, Richard Guy Briggs <rgb at redhat.com> wrote:
> The existing condition tested for process effective capabilities set by
> file attributes but intended to ignore the change if the result was
> unsurprisingly an effective full set in the case root is special with a
> setuid root executable file and we are root.
>
> Stated again:
> - When you execute a setuid root application, it is no surprise and
> expected that it got all capabilities, so we do not want capabilities
> recorded.
> if (pE_grew && !(pE_fullset && (eff_root || real_root) && root_priveleged) )
>
> Now make sure we cover other cases:
> - If something prevented a setuid root app getting all capabilities and
> it wound up with one capability only, then it is a surprise and should
> be logged. When it is a setuid root file, we only want capabilities
> when the process does not get full capabilities..
> root_priveleged && setuid_root && !pE_fullset
>
> - Similarly if a non-setuid program does pick up capabilities due to
> file system based capabilities, then we want to know what capabilities
> were picked up. When it has file system based capabilities we want
> the capabilities.
> !is_setuid && (has_fcap && pP_gained)
>
> - If it is a non-setuid file and it gets ambient capabilities, we want
> the capabilities.
> !is_setuid && pA_gained
>
> - These last two are combined into one due to the common first parameter.
>
> Related: https://github.com/linux-audit/audit-kernel/issues/16
>
> Signed-off-by: Richard Guy Briggs <rgb at redhat.com>
> Reviewed-by: Serge Hallyn <serge at hallyn.com>
> Acked-by: James Morris <james.l.morris at oracle.com>
> ---
> security/commoncap.c | 29 ++++++++++++++++++++++-------
> 1 files changed, 22 insertions(+), 7 deletions(-)
I really don't like how this patchset has gotten so large, I would
have preferred to see a patch (or two, or three, ...) that made the
minimal number of changes necessary to fix the audit problem and then
a follow-on patchset to do the rework you felt was worthwhile.
Reviewing this was a real pain and I have very little confidence in my
conclusions, please try to not do this again.
Acked-by: Paul Moore <paul at paul-moore.com>
> diff --git a/security/commoncap.c b/security/commoncap.c
> index 759f3fa..afebfd3 100644
> --- a/security/commoncap.c
> +++ b/security/commoncap.c
> @@ -528,7 +528,7 @@ static inline bool __is_setgid(struct cred *new, const struct cred *old)
> { return !gid_eq(new->egid, old->gid); }
>
> /*
> - * Audit candidate if current->cap_effective is set
> + * 1) Audit candidate if current->cap_effective is set
> *
> * We do not bother to audit if 3 things are true:
> * 1) cap_effective has all caps
> @@ -538,16 +538,31 @@ static inline bool __is_setgid(struct cred *new, const struct cred *old)
> *
> * Number 1 above might fail if you don't have a full bset, but I think
> * that is interesting information to audit.
> + *
> + * A number of other conditions require logging:
> + * 2) something prevented setuid root getting all caps
> + * 3) non-setuid root gets fcaps
> + * 4) non-setuid root gets ambient
> */
> -static inline bool nonroot_raised_pE(struct cred *cred, kuid_t root)
> +static inline bool nonroot_raised_pE(struct cred *new, const struct cred *old,
> + kuid_t root, bool has_fcap)
> {
> bool ret = false;
>
> - if (__cap_grew(effective, ambient, cred) &&
> - !(__cap_full(effective, cred) &&
> - (__is_eff(root, cred) || __is_real(root, cred)) &&
> - root_privileged()))
> + if ((__cap_grew(effective, ambient, new) &&
> + !(__cap_full(effective, new) &&
> + (__is_eff(root, new) || __is_real(root, new)) &&
> + root_privileged())) ||
> + (root_privileged() &&
> + __is_suid(root, new) &&
> + !__cap_full(effective, new)) ||
> + (!__is_setuid(new, old) &&
> + ((has_fcap &&
> + __cap_gained(permitted, new, old)) ||
> + __cap_gained(ambient, new, old))))
> +
> ret = true;
> +
> return ret;
> }
>
> @@ -628,7 +643,7 @@ int cap_bprm_set_creds(struct linux_binprm *bprm)
> if (WARN_ON(!cap_ambient_invariant_ok(new)))
> return -EPERM;
>
> - if (nonroot_raised_pE(new, root_uid)) {
> + if (nonroot_raised_pE(new, old, root_uid, has_fcap)) {
> ret = audit_log_bprm_fcaps(bprm, new, old);
> if (ret < 0)
> return ret;
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
paul moore
www.paul-moore.com
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
More information about the Linux-security-module-archive
mailing list