Message ID | 20190818235745.1417-2-roberto.sassu@huawei.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Introduce Infoflow LSM | expand |
On 8/18/2019 4:57 PM, Roberto Sassu wrote: > The LSM hooks audit_rule_known() and audit_rule_match() define 1 as > result for successful operation. However, the security_ functions use > call_int_hook() which stops iterating over LSMs if the result is not > zero. > > Introduce call_int_hook_and(), so that the final result returned by the > security_ functions is 1 if all LSMs return 1. I don't think this is what you want. You want an audit record generated if any of the security modules want one, not only if all of the security modules want one. > > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> > --- > security/security.c | 19 +++++++++++++++++-- > 1 file changed, 17 insertions(+), 2 deletions(-) > > diff --git a/security/security.c b/security/security.c > index cbee0b7915d5..ff1736ee3410 100644 > --- a/security/security.c > +++ b/security/security.c > @@ -634,6 +634,20 @@ static void __init lsm_early_task(struct task_struct *task) > RC; \ > }) > > +#define call_int_hook_and(FUNC, IRC, ...) ({ \ > + int RC = IRC; \ > + do { \ > + struct security_hook_list *P; \ > + \ > + hlist_for_each_entry(P, &security_hook_heads.FUNC, list) { \ > + RC = P->hook.FUNC(__VA_ARGS__); \ > + if (!RC) \ > + break; \ > + } \ > + } while (0); \ > + RC; \ > +}) > + > /* Security operations */ > > int security_binder_set_context_mgr(struct task_struct *mgr) > @@ -2339,7 +2353,7 @@ int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule) > > int security_audit_rule_known(struct audit_krule *krule) > { > - return call_int_hook(audit_rule_known, 0, krule); > + return call_int_hook_and(audit_rule_known, 0, krule); > } > > void security_audit_rule_free(void *lsmrule) > @@ -2349,7 +2363,8 @@ void security_audit_rule_free(void *lsmrule) > > int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule) > { > - return call_int_hook(audit_rule_match, 0, secid, field, op, lsmrule); > + return call_int_hook_and(audit_rule_match, 0, secid, field, op, > + lsmrule); > } > #endif /* CONFIG_AUDIT */ >
> -----Original Message----- > From: Casey Schaufler [mailto:casey@schaufler-ca.com] > Sent: Monday, August 19, 2019 4:52 PM > To: Roberto Sassu <roberto.sassu@huawei.com>; linux- > integrity@vger.kernel.org > Cc: linux-security-module@vger.kernel.org; zohar@linux.ibm.com; Dmitry > Kasatkin <dmitry.kasatkin@huawei.com>; Silviu Vlasceanu > <Silviu.Vlasceanu@huawei.com> > Subject: Re: [WIP][RFC][PATCH 1/3] security: introduce call_int_hook_and() > macro > > On 8/18/2019 4:57 PM, Roberto Sassu wrote: > > The LSM hooks audit_rule_known() and audit_rule_match() define 1 as > > result for successful operation. However, the security_ functions use > > call_int_hook() which stops iterating over LSMs if the result is not > > zero. > > > > Introduce call_int_hook_and(), so that the final result returned by > > the security_ functions is 1 if all LSMs return 1. > > I don't think this is what you want. You want an audit record generated if > any of the security modules want one, not only if all of the security modules > want one. Right, it would be better if I can specify the prefix of the LSM that should execute the audit_rule_match() hook. For example, I would like to specify in the IMA policy: measure subj_type=infoflow:tcb 'infoflow:tcb' would be the value of the 'lsmrule' parameter of security_audit_rule_match(). The rule would be evaluated only by Infoflow LSM, and not SELinux. Roberto
diff --git a/security/security.c b/security/security.c index cbee0b7915d5..ff1736ee3410 100644 --- a/security/security.c +++ b/security/security.c @@ -634,6 +634,20 @@ static void __init lsm_early_task(struct task_struct *task) RC; \ }) +#define call_int_hook_and(FUNC, IRC, ...) ({ \ + int RC = IRC; \ + do { \ + struct security_hook_list *P; \ + \ + hlist_for_each_entry(P, &security_hook_heads.FUNC, list) { \ + RC = P->hook.FUNC(__VA_ARGS__); \ + if (!RC) \ + break; \ + } \ + } while (0); \ + RC; \ +}) + /* Security operations */ int security_binder_set_context_mgr(struct task_struct *mgr) @@ -2339,7 +2353,7 @@ int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule) int security_audit_rule_known(struct audit_krule *krule) { - return call_int_hook(audit_rule_known, 0, krule); + return call_int_hook_and(audit_rule_known, 0, krule); } void security_audit_rule_free(void *lsmrule) @@ -2349,7 +2363,8 @@ void security_audit_rule_free(void *lsmrule) int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule) { - return call_int_hook(audit_rule_match, 0, secid, field, op, lsmrule); + return call_int_hook_and(audit_rule_match, 0, secid, field, op, + lsmrule); } #endif /* CONFIG_AUDIT */
The LSM hooks audit_rule_known() and audit_rule_match() define 1 as result for successful operation. However, the security_ functions use call_int_hook() which stops iterating over LSMs if the result is not zero. Introduce call_int_hook_and(), so that the final result returned by the security_ functions is 1 if all LSMs return 1. Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> --- security/security.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-)