UBUNTU: SAUCE: apparmor4.0.0 [04/90]: LSM stacking v39: IMA: avoid label collisions with stacked LSMs
BugLink: http://bugs.launchpad.net/bugs/2028253 Integrity measurement may filter on security module information and needs to be clear in the case of multiple active security modules which applies. Provide a boot option ima_rules_lsm= to allow the user to specify an active security module to apply filters to. If not specified, use the first registered module that supports the audit_rule_match() LSM hook. Allow the user to specify in the IMA policy an lsm= option to specify the security module to use for a particular rule. This requires adding the LSM of interest as a parameter to three of the audit hooks. Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> To: Mimi Zohar <zohar@linux.ibm.com> To: linux-integrity@vger.kernel.org To: audit@vger.kernel.org (cherry picked from commit d177f98409d82dbb23763122fd1e4eb9897cf6ac https://git.launchpad.net/~apparmor-dev/ubuntu-kernel-next) Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
This commit is contained in:
committed by
Paolo Pisati
parent
51e1dcf334
commit
e1a8c296ec
@@ -26,7 +26,7 @@ Description:
|
||||
[uid=] [euid=] [gid=] [egid=]
|
||||
[fowner=] [fgroup=]]
|
||||
lsm: [[subj_user=] [subj_role=] [subj_type=]
|
||||
[obj_user=] [obj_role=] [obj_type=]]
|
||||
[obj_user=] [obj_role=] [obj_type=] [lsm=]]
|
||||
option: [digest_type=] [template=] [permit_directio]
|
||||
[appraise_type=] [appraise_flag=]
|
||||
[appraise_algos=] [keyrings=]
|
||||
@@ -138,6 +138,12 @@ Description:
|
||||
|
||||
measure subj_user=_ func=FILE_CHECK mask=MAY_READ
|
||||
|
||||
It is possible to explicitly specify which security
|
||||
module a rule applies to using lsm=. If the security
|
||||
module specified is not active on the system the rule
|
||||
will be rejected. If lsm= is not specified the first
|
||||
security module registered on the system will be assumed.
|
||||
|
||||
Example of measure rules using alternate PCRs::
|
||||
|
||||
measure func=KEXEC_KERNEL_CHECK pcr=4
|
||||
|
||||
@@ -394,10 +394,11 @@ LSM_HOOK(int, 0, key_getsecurity, struct key *key, char **buffer)
|
||||
|
||||
#ifdef CONFIG_AUDIT
|
||||
LSM_HOOK(int, 0, audit_rule_init, u32 field, u32 op, char *rulestr,
|
||||
void **lsmrule)
|
||||
void **lsmrule, int lsmid)
|
||||
LSM_HOOK(int, 0, audit_rule_known, struct audit_krule *krule)
|
||||
LSM_HOOK(int, 0, audit_rule_match, u32 secid, u32 field, u32 op, void *lsmrule)
|
||||
LSM_HOOK(void, LSM_RET_VOID, audit_rule_free, void *lsmrule)
|
||||
LSM_HOOK(int, 0, audit_rule_match, u32 secid, u32 field, u32 op, void *lsmrule,
|
||||
int lsmid)
|
||||
LSM_HOOK(void, LSM_RET_VOID, audit_rule_free, void *lsmrule, int lsmid)
|
||||
#endif /* CONFIG_AUDIT */
|
||||
|
||||
#ifdef CONFIG_BPF_SYSCALL
|
||||
|
||||
@@ -286,6 +286,8 @@ int unregister_blocking_lsm_notifier(struct notifier_block *nb);
|
||||
extern int security_init(void);
|
||||
extern int early_security_init(void);
|
||||
extern u64 lsm_name_to_attr(const char *name);
|
||||
extern u64 lsm_name_to_id(const char *name);
|
||||
extern const char *lsm_id_to_name(u64 id);
|
||||
|
||||
/* Security operations */
|
||||
int security_binder_set_context_mgr(const struct cred *mgr);
|
||||
@@ -539,6 +541,16 @@ static inline u64 lsm_name_to_attr(const char *name)
|
||||
return LSM_ATTR_UNDEF;
|
||||
}
|
||||
|
||||
static inline u64 lsm_name_to_id(const char *name)
|
||||
{
|
||||
return LSM_ID_UNDEF;
|
||||
}
|
||||
|
||||
static inline const char *lsm_id_to_name(u64 id)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void security_free_mnt_opts(void **mnt_opts)
|
||||
{
|
||||
}
|
||||
@@ -2044,25 +2056,27 @@ static inline void security_audit_rule_free(void *lsmrule)
|
||||
#endif /* CONFIG_AUDIT */
|
||||
|
||||
#if defined(CONFIG_IMA_LSM_RULES) && defined(CONFIG_SECURITY)
|
||||
int ima_filter_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule);
|
||||
int ima_filter_rule_match(u32 secid, u32 field, u32 op, void *lsmrule);
|
||||
void ima_filter_rule_free(void *lsmrule);
|
||||
int ima_filter_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule,
|
||||
int lsmid);
|
||||
int ima_filter_rule_match(u32 secid, u32 field, u32 op, void *lsmrule,
|
||||
int lsmid);
|
||||
void ima_filter_rule_free(void *lsmrule, int lsmid);
|
||||
|
||||
#else
|
||||
|
||||
static inline int ima_filter_rule_init(u32 field, u32 op, char *rulestr,
|
||||
void **lsmrule)
|
||||
void **lsmrule, int lsmid)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ima_filter_rule_match(u32 secid, u32 field, u32 op,
|
||||
void *lsmrule)
|
||||
void *lsmrule, int lsmid)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void ima_filter_rule_free(void *lsmrule)
|
||||
static inline void ima_filter_rule_free(void *lsmrule, int lsmid)
|
||||
{ }
|
||||
|
||||
#endif /* defined(CONFIG_IMA_LSM_RULES) && defined(CONFIG_SECURITY) */
|
||||
|
||||
@@ -206,10 +206,13 @@ struct aa_audit_rule {
|
||||
struct aa_label *label;
|
||||
};
|
||||
|
||||
void aa_audit_rule_free(void *vrule)
|
||||
/****************************** audit rules *******************************/
|
||||
void aa_audit_rule_free(void *vrule, int lsmid)
|
||||
{
|
||||
struct aa_audit_rule *rule = vrule;
|
||||
|
||||
if (lsmid != LSM_ID_UNDEF || lsmid != LSM_ID_APPARMOR)
|
||||
return;
|
||||
if (rule) {
|
||||
if (!IS_ERR(rule->label))
|
||||
aa_put_label(rule->label);
|
||||
@@ -217,10 +220,13 @@ void aa_audit_rule_free(void *vrule)
|
||||
}
|
||||
}
|
||||
|
||||
int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
|
||||
int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule,
|
||||
int lsmid)
|
||||
{
|
||||
struct aa_audit_rule *rule;
|
||||
|
||||
if (lsmid != LSM_ID_UNDEF || lsmid != LSM_ID_APPARMOR)
|
||||
return 0;
|
||||
switch (field) {
|
||||
case AUDIT_SUBJ_ROLE:
|
||||
if (op != Audit_equal && op != Audit_not_equal)
|
||||
@@ -240,7 +246,7 @@ int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
|
||||
GFP_KERNEL, true, false);
|
||||
if (IS_ERR(rule->label)) {
|
||||
int err = PTR_ERR(rule->label);
|
||||
aa_audit_rule_free(rule);
|
||||
aa_audit_rule_free(rule, LSM_ID_APPARMOR);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -264,12 +270,14 @@ int aa_audit_rule_known(struct audit_krule *rule)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aa_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule)
|
||||
int aa_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, int lsmid)
|
||||
{
|
||||
struct aa_audit_rule *rule = vrule;
|
||||
struct aa_label *label;
|
||||
int found = 0;
|
||||
|
||||
if (lsmid != LSM_ID_UNDEF || lsmid != LSM_ID_APPARMOR)
|
||||
return 0;
|
||||
label = aa_secid_to_label(sid);
|
||||
|
||||
if (!label)
|
||||
|
||||
@@ -199,9 +199,10 @@ static inline int complain_error(int error)
|
||||
return error;
|
||||
}
|
||||
|
||||
void aa_audit_rule_free(void *vrule);
|
||||
int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule);
|
||||
void aa_audit_rule_free(void *vrule, int lsmid);
|
||||
int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule,
|
||||
int lsmid);
|
||||
int aa_audit_rule_known(struct audit_krule *rule);
|
||||
int aa_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule);
|
||||
int aa_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, int lsmid);
|
||||
|
||||
#endif /* __AA_AUDIT_H */
|
||||
|
||||
@@ -117,6 +117,8 @@ struct ima_rule_entry {
|
||||
void *rule; /* LSM file metadata specific */
|
||||
char *args_p; /* audit value */
|
||||
int type; /* audit type */
|
||||
int lsm_id; /* which LSM rule applies to */
|
||||
bool lsm_specific; /* true if lsm is specified */
|
||||
} lsm[MAX_LSM_RULES];
|
||||
char *fsname;
|
||||
struct ima_rule_opt_list *keyrings; /* Measure keys added to these keyrings */
|
||||
@@ -309,6 +311,25 @@ static int __init default_appraise_policy_setup(char *str)
|
||||
}
|
||||
__setup("ima_appraise_tcb", default_appraise_policy_setup);
|
||||
|
||||
static int default_rules_lsm __ro_after_init = LSM_ID_UNDEF;
|
||||
|
||||
static int __init ima_rules_lsm_init(char *str)
|
||||
{
|
||||
int newdrl;
|
||||
|
||||
newdrl = lsm_name_to_id(str);
|
||||
if (newdrl >= 0) {
|
||||
default_rules_lsm = newdrl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
pr_err("default ima rule lsm \"%s\" not registered, value unchanged.",
|
||||
str);
|
||||
|
||||
return 1;
|
||||
}
|
||||
__setup("ima_rules_lsm=", ima_rules_lsm_init);
|
||||
|
||||
static struct ima_rule_opt_list *ima_alloc_rule_opt_list(const substring_t *src)
|
||||
{
|
||||
struct ima_rule_opt_list *opt_list;
|
||||
@@ -380,7 +401,8 @@ static void ima_lsm_free_rule(struct ima_rule_entry *entry)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_LSM_RULES; i++) {
|
||||
ima_filter_rule_free(entry->lsm[i].rule);
|
||||
ima_filter_rule_free(entry->lsm[i].rule,
|
||||
entry->lsm[i].lsm_id);
|
||||
kfree(entry->lsm[i].args_p);
|
||||
}
|
||||
}
|
||||
@@ -425,7 +447,8 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry)
|
||||
|
||||
ima_filter_rule_init(nentry->lsm[i].type, Audit_equal,
|
||||
nentry->lsm[i].args_p,
|
||||
&nentry->lsm[i].rule);
|
||||
&nentry->lsm[i].rule,
|
||||
entry->lsm[i].lsm_id);
|
||||
if (!nentry->lsm[i].rule)
|
||||
pr_warn("rule for LSM \'%s\' is undefined\n",
|
||||
nentry->lsm[i].args_p);
|
||||
@@ -451,7 +474,8 @@ static int ima_lsm_update_rule(struct ima_rule_entry *entry)
|
||||
* be owned by nentry.
|
||||
*/
|
||||
for (i = 0; i < MAX_LSM_RULES; i++)
|
||||
ima_filter_rule_free(entry->lsm[i].rule);
|
||||
ima_filter_rule_free(entry->lsm[i].rule,
|
||||
entry->lsm[i].lsm_id);
|
||||
kfree(entry);
|
||||
|
||||
return 0;
|
||||
@@ -650,14 +674,16 @@ retry:
|
||||
security_inode_getsecid(inode, &osid);
|
||||
rc = ima_filter_rule_match(osid, lsm_rule->lsm[i].type,
|
||||
Audit_equal,
|
||||
lsm_rule->lsm[i].rule);
|
||||
lsm_rule->lsm[i].rule,
|
||||
lsm_rule->lsm[i].lsm_id);
|
||||
break;
|
||||
case LSM_SUBJ_USER:
|
||||
case LSM_SUBJ_ROLE:
|
||||
case LSM_SUBJ_TYPE:
|
||||
rc = ima_filter_rule_match(secid, lsm_rule->lsm[i].type,
|
||||
Audit_equal,
|
||||
lsm_rule->lsm[i].rule);
|
||||
lsm_rule->lsm[i].rule,
|
||||
lsm_rule->lsm[i].lsm_id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -680,7 +706,8 @@ retry:
|
||||
out:
|
||||
if (rule_reinitialized) {
|
||||
for (i = 0; i < MAX_LSM_RULES; i++)
|
||||
ima_filter_rule_free(lsm_rule->lsm[i].rule);
|
||||
ima_filter_rule_free(lsm_rule->lsm[i].rule,
|
||||
lsm_rule->lsm[i].lsm_id);
|
||||
kfree(lsm_rule);
|
||||
}
|
||||
return result;
|
||||
@@ -1073,7 +1100,7 @@ enum policy_opt {
|
||||
Opt_digest_type,
|
||||
Opt_appraise_type, Opt_appraise_flag, Opt_appraise_algos,
|
||||
Opt_permit_directio, Opt_pcr, Opt_template, Opt_keyrings,
|
||||
Opt_label, Opt_err
|
||||
Opt_lsm, Opt_label, Opt_err
|
||||
};
|
||||
|
||||
static const match_table_t policy_tokens = {
|
||||
@@ -1121,6 +1148,7 @@ static const match_table_t policy_tokens = {
|
||||
{Opt_pcr, "pcr=%s"},
|
||||
{Opt_template, "template=%s"},
|
||||
{Opt_keyrings, "keyrings=%s"},
|
||||
{Opt_lsm, "lsm=%s"},
|
||||
{Opt_label, "label=%s"},
|
||||
{Opt_err, NULL}
|
||||
};
|
||||
@@ -1140,7 +1168,8 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry,
|
||||
entry->lsm[lsm_rule].type = audit_type;
|
||||
result = ima_filter_rule_init(entry->lsm[lsm_rule].type, Audit_equal,
|
||||
entry->lsm[lsm_rule].args_p,
|
||||
&entry->lsm[lsm_rule].rule);
|
||||
&entry->lsm[lsm_rule].rule,
|
||||
entry->lsm[lsm_rule].lsm_id);
|
||||
if (!entry->lsm[lsm_rule].rule) {
|
||||
pr_warn("rule for LSM \'%s\' is undefined\n",
|
||||
entry->lsm[lsm_rule].args_p);
|
||||
@@ -1878,6 +1907,23 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
|
||||
&(template_desc->num_fields));
|
||||
entry->template = template_desc;
|
||||
break;
|
||||
case Opt_lsm: {
|
||||
int i;
|
||||
|
||||
result = lsm_name_to_id(args[0].from);
|
||||
if (result < 0) {
|
||||
for (i = 0; i < MAX_LSM_RULES; i++)
|
||||
entry->lsm[i].args_p = NULL;
|
||||
result = -EINVAL;
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < MAX_LSM_RULES; i++) {
|
||||
entry->lsm[i].lsm_id = result;
|
||||
entry->lsm[i].lsm_specific = true;
|
||||
}
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
case Opt_err:
|
||||
ima_log_string(ab, "UNKNOWN", p);
|
||||
result = -EINVAL;
|
||||
@@ -1923,6 +1969,7 @@ ssize_t ima_parse_add_rule(char *rule)
|
||||
struct ima_rule_entry *entry;
|
||||
ssize_t result, len;
|
||||
int audit_info = 0;
|
||||
int i;
|
||||
|
||||
p = strsep(&rule, "\n");
|
||||
len = strlen(p) + 1;
|
||||
@@ -1940,6 +1987,11 @@ ssize_t ima_parse_add_rule(char *rule)
|
||||
|
||||
INIT_LIST_HEAD(&entry->list);
|
||||
|
||||
for (i = 0; i < MAX_LSM_RULES; i++) {
|
||||
entry->lsm[i].lsm_id = default_rules_lsm;
|
||||
entry->lsm[i].lsm_specific = false;
|
||||
}
|
||||
|
||||
result = ima_parse_rule(p, entry);
|
||||
if (result) {
|
||||
ima_free_rule(entry);
|
||||
@@ -2251,6 +2303,9 @@ int ima_policy_show(struct seq_file *m, void *v)
|
||||
entry->lsm[i].args_p);
|
||||
break;
|
||||
}
|
||||
if (entry->lsm[i].lsm_specific)
|
||||
seq_printf(m, pt(Opt_lsm),
|
||||
lsm_id_to_name(entry->lsm[i].lsm_id));
|
||||
seq_puts(m, " ");
|
||||
}
|
||||
}
|
||||
|
||||
+55
-9
@@ -272,6 +272,46 @@ static void __init initialize_lsm(struct lsm_info *lsm)
|
||||
u32 lsm_active_cnt __ro_after_init;
|
||||
const struct lsm_id *lsm_idlist[LSM_CONFIG_COUNT];
|
||||
|
||||
/**
|
||||
* lsm_name_to_id - get the LSM ID for a registered LSM
|
||||
* @name: the name of the LSM
|
||||
*
|
||||
* Returns the LSM ID associated with the named LSM or
|
||||
* LSM_ID_UNDEF if the name isn't recongnized.
|
||||
*/
|
||||
u64 lsm_name_to_id(const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < LSM_CONFIG_COUNT; i++) {
|
||||
if (!lsm_idlist[i]->name)
|
||||
return LSM_ID_UNDEF;
|
||||
if (!strcmp(name, lsm_idlist[i]->name))
|
||||
return lsm_idlist[i]->id;
|
||||
}
|
||||
return LSM_ID_UNDEF;
|
||||
}
|
||||
|
||||
/**
|
||||
* lsm_id_to_name - get the LSM name for a registered LSM ID
|
||||
* @id: the ID of the LSM
|
||||
*
|
||||
* Returns the LSM name associated with the LSM ID or
|
||||
* NULL if the ID isn't recongnized.
|
||||
*/
|
||||
const char *lsm_id_to_name(u64 id)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < LSM_CONFIG_COUNT; i++) {
|
||||
if (!lsm_idlist[i]->name)
|
||||
return NULL;
|
||||
if (id == lsm_idlist[i]->id)
|
||||
return lsm_idlist[i]->name;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Populate ordered LSMs list from comma-separated LSM name list. */
|
||||
static void __init ordered_lsm_parse(const char *order, const char *origin)
|
||||
{
|
||||
@@ -5390,7 +5430,8 @@ int security_key_getsecurity(struct key *key, char **buffer)
|
||||
*/
|
||||
int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule)
|
||||
{
|
||||
return call_int_hook(audit_rule_init, 0, field, op, rulestr, lsmrule);
|
||||
return call_int_hook(audit_rule_init, 0, field, op, rulestr, lsmrule,
|
||||
LSM_ID_UNDEF);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5416,7 +5457,7 @@ int security_audit_rule_known(struct audit_krule *krule)
|
||||
*/
|
||||
void security_audit_rule_free(void *lsmrule)
|
||||
{
|
||||
call_void_hook(audit_rule_free, lsmrule);
|
||||
call_void_hook(audit_rule_free, lsmrule, LSM_ID_UNDEF);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5434,7 +5475,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(audit_rule_match, 0, secid, field, op, lsmrule,
|
||||
LSM_ID_UNDEF);
|
||||
}
|
||||
#endif /* CONFIG_AUDIT */
|
||||
|
||||
@@ -5443,19 +5485,23 @@ int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule)
|
||||
* The integrity subsystem uses the same hooks as
|
||||
* the audit subsystem.
|
||||
*/
|
||||
int ima_filter_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule)
|
||||
int ima_filter_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule,
|
||||
int lsmid)
|
||||
{
|
||||
return call_int_hook(audit_rule_init, 0, field, op, rulestr, lsmrule);
|
||||
return call_int_hook(audit_rule_init, 0, field, op, rulestr, lsmrule,
|
||||
lsmid);
|
||||
}
|
||||
|
||||
void ima_filter_rule_free(void *lsmrule)
|
||||
void ima_filter_rule_free(void *lsmrule, int lsmid)
|
||||
{
|
||||
call_void_hook(audit_rule_free, lsmrule);
|
||||
call_void_hook(audit_rule_free, lsmrule, lsmid);
|
||||
}
|
||||
|
||||
int ima_filter_rule_match(u32 secid, u32 field, u32 op, void *lsmrule)
|
||||
int ima_filter_rule_match(u32 secid, u32 field, u32 op, void *lsmrule,
|
||||
int lsmid)
|
||||
{
|
||||
return call_int_hook(audit_rule_match, 0, secid, field, op, lsmrule);
|
||||
return call_int_hook(audit_rule_match, 0, secid, field, op, lsmrule,
|
||||
lsmid);
|
||||
}
|
||||
#endif /* CONFIG_IMA_LSM_RULES */
|
||||
|
||||
|
||||
@@ -21,21 +21,24 @@
|
||||
* @op: the operator the rule uses
|
||||
* @rulestr: the text "target" of the rule
|
||||
* @rule: pointer to the new rule structure returned via this
|
||||
* @lsmid: the relevant LSM
|
||||
*
|
||||
* Returns 0 if successful, -errno if not. On success, the rule structure
|
||||
* will be allocated internally. The caller must free this structure with
|
||||
* selinux_audit_rule_free() after use.
|
||||
*/
|
||||
int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **rule);
|
||||
int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **rule,
|
||||
int lsmid);
|
||||
|
||||
/**
|
||||
* selinux_audit_rule_free - free an selinux audit rule structure.
|
||||
* @rule: pointer to the audit rule to be freed
|
||||
* @lsmid: which LSM this rule relates to
|
||||
*
|
||||
* This will free all memory associated with the given rule.
|
||||
* If @rule is NULL, no operation is performed.
|
||||
*/
|
||||
void selinux_audit_rule_free(void *rule);
|
||||
void selinux_audit_rule_free(void *rule, int lsmid);
|
||||
|
||||
/**
|
||||
* selinux_audit_rule_match - determine if a context ID matches a rule.
|
||||
@@ -43,11 +46,12 @@ void selinux_audit_rule_free(void *rule);
|
||||
* @field: the field this rule refers to
|
||||
* @op: the operator the rule uses
|
||||
* @rule: pointer to the audit rule to check against
|
||||
* @lsmid: the relevant LSM
|
||||
*
|
||||
* Returns 1 if the context id matches the rule, 0 if it does not, and
|
||||
* -errno on failure.
|
||||
*/
|
||||
int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *rule);
|
||||
int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *rule, int lsmid);
|
||||
|
||||
/**
|
||||
* selinux_audit_rule_known - check to see if rule contains selinux fields.
|
||||
|
||||
@@ -3498,17 +3498,20 @@ struct selinux_audit_rule {
|
||||
struct context au_ctxt;
|
||||
};
|
||||
|
||||
void selinux_audit_rule_free(void *vrule)
|
||||
void selinux_audit_rule_free(void *vrule, int lsmid)
|
||||
{
|
||||
struct selinux_audit_rule *rule = vrule;
|
||||
|
||||
if (lsmid != LSM_ID_UNDEF || lsmid != LSM_ID_SELINUX)
|
||||
return;
|
||||
if (rule) {
|
||||
context_destroy(&rule->au_ctxt);
|
||||
kfree(rule);
|
||||
}
|
||||
}
|
||||
|
||||
int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
|
||||
int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule,
|
||||
int lsmid)
|
||||
{
|
||||
struct selinux_state *state = &selinux_state;
|
||||
struct selinux_policy *policy;
|
||||
@@ -3522,6 +3525,8 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
|
||||
|
||||
*rule = NULL;
|
||||
|
||||
if (lsmid != LSM_ID_UNDEF || lsmid != LSM_ID_SELINUX)
|
||||
return 0;
|
||||
if (!selinux_initialized())
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
@@ -3603,7 +3608,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
|
||||
|
||||
err:
|
||||
rcu_read_unlock();
|
||||
selinux_audit_rule_free(tmprule);
|
||||
selinux_audit_rule_free(tmprule, LSM_ID_SELINUX);
|
||||
*rule = NULL;
|
||||
return rc;
|
||||
}
|
||||
@@ -3633,7 +3638,7 @@ int selinux_audit_rule_known(struct audit_krule *rule)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule)
|
||||
int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, int lsmid)
|
||||
{
|
||||
struct selinux_state *state = &selinux_state;
|
||||
struct selinux_policy *policy;
|
||||
@@ -3642,6 +3647,8 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule)
|
||||
struct selinux_audit_rule *rule = vrule;
|
||||
int match = 0;
|
||||
|
||||
if (lsmid != LSM_ID_UNDEF || lsmid != LSM_ID_SELINUX)
|
||||
return 0;
|
||||
if (unlikely(!rule)) {
|
||||
WARN_ONCE(1, "selinux_audit_rule_match: missing rule\n");
|
||||
return -ENOENT;
|
||||
|
||||
@@ -4673,16 +4673,20 @@ static int smack_post_notification(const struct cred *w_cred,
|
||||
* @op: required testing operator (=, !=, >, <, ...)
|
||||
* @rulestr: smack label to be audited
|
||||
* @vrule: pointer to save our own audit rule representation
|
||||
* @lsmid: the relevant LSM
|
||||
*
|
||||
* Prepare to audit cases where (@field @op @rulestr) is true.
|
||||
* The label to be audited is created if necessay.
|
||||
*/
|
||||
static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
|
||||
static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule,
|
||||
int lsmid)
|
||||
{
|
||||
struct smack_known *skp;
|
||||
char **rule = (char **)vrule;
|
||||
*rule = NULL;
|
||||
|
||||
if (lsmid != LSM_ID_UNDEF || lsmid != LSM_ID_SMACK)
|
||||
return 0;
|
||||
if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -4727,15 +4731,19 @@ static int smack_audit_rule_known(struct audit_krule *krule)
|
||||
* @field: audit rule flags given from user-space
|
||||
* @op: required testing operator
|
||||
* @vrule: smack internal rule presentation
|
||||
* @lsmid: the relevant LSM
|
||||
*
|
||||
* The core Audit hook. It's used to take the decision of
|
||||
* whether to audit or not to audit a given object.
|
||||
*/
|
||||
static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule)
|
||||
static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
|
||||
int lsmid)
|
||||
{
|
||||
struct smack_known *skp;
|
||||
char *rule = vrule;
|
||||
|
||||
if (lsmid != LSM_ID_UNDEF || lsmid != LSM_ID_SMACK)
|
||||
return 0;
|
||||
if (unlikely(!rule)) {
|
||||
WARN_ONCE(1, "Smack: missing rule\n");
|
||||
return -ENOENT;
|
||||
|
||||
Reference in New Issue
Block a user