Extend the IMA policy language with "mode=IXUGO" to identify files with the execute mode bit enabled. Examples: measure func=FILE_CHECK mode=IXUGO appraise func=FILE_CHECK appraise_type=imasig mode=IXUGO Suggested-by: Steve Grubb <sgrubb@xxxxxxxxxx> (based on execute mode bit) Signed-off-by: Mimi Zohar <zohar@xxxxxxxxxxxxx> --- Documentation/ABI/testing/ima_policy | 5 +++-- security/integrity/ima/ima_policy.c | 18 ++++++++++++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy index cd572912c593..a12e784cee31 100644 --- a/Documentation/ABI/testing/ima_policy +++ b/Documentation/ABI/testing/ima_policy @@ -20,8 +20,8 @@ Description: action: measure | dont_measure | appraise | dont_appraise | audit | hash | dont_hash condition:= base | lsm [option] - base: [[func=] [mask=] [fsmagic=] [fsuuid=] [uid=] - [euid=] [fowner=] [fsname=]] + base: [[func=] [mask=] [mode=] [fsmagic=] [fsuuid=] + [uid=] [euid=] [fowner=] [fsname=]] lsm: [[subj_user=] [subj_role=] [subj_type=] [obj_user=] [obj_role=] [obj_type=]] option: [[appraise_type=]] [template=] [permit_directio] @@ -32,6 +32,7 @@ Description: [KEXEC_CMDLINE] [KEY_CHECK] mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND] [[^]MAY_EXEC] + mode:= [IXUGO] fsmagic:= hex value fsuuid:= file system UUID (e.g 8bcbe394-4f13-4144-be8e-5aa9ea2ce2f6) uid:= decimal value diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index ef7f68cc935e..28b68e076638 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -33,6 +33,7 @@ #define IMA_PCR 0x0100 #define IMA_FSNAME 0x0200 #define IMA_KEYRINGS 0x0400 +#define IMA_IXUGO 0x0800 #define UNKNOWN 0 #define MEASURE 0x0001 /* same as IMA_MEASURE */ @@ -435,6 +436,8 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, if ((rule->flags & IMA_INMASK) && (!(rule->mask & mask) && func != POST_SETATTR)) return false; + if ((rule->flags & IMA_IXUGO) && !(inode->i_mode & S_IXUGO)) + return false; if ((rule->flags & IMA_FSMAGIC) && rule->fsmagic != inode->i_sb->s_magic) return false; @@ -459,6 +462,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, if ((rule->flags & IMA_FOWNER) && !rule->fowner_op(inode->i_uid, rule->fowner)) return false; + for (i = 0; i < MAX_LSM_RULES; i++) { int rc = 0; u32 osid; @@ -822,7 +826,7 @@ enum { Opt_audit, Opt_hash, Opt_dont_hash, Opt_obj_user, Opt_obj_role, Opt_obj_type, Opt_subj_user, Opt_subj_role, Opt_subj_type, - Opt_func, Opt_mask, Opt_fsmagic, Opt_fsname, + Opt_func, Opt_mask, Opt_mode, Opt_fsmagic, Opt_fsname, Opt_fsuuid, Opt_uid_eq, Opt_euid_eq, Opt_fowner_eq, Opt_uid_gt, Opt_euid_gt, Opt_fowner_gt, Opt_uid_lt, Opt_euid_lt, Opt_fowner_lt, @@ -847,6 +851,7 @@ static const match_table_t policy_tokens = { {Opt_subj_type, "subj_type=%s"}, {Opt_func, "func=%s"}, {Opt_mask, "mask=%s"}, + {Opt_mode, "mode=%s"}, {Opt_fsmagic, "fsmagic=%s"}, {Opt_fsname, "fsname=%s"}, {Opt_fsuuid, "fsuuid=%s"}, @@ -1098,6 +1103,13 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) entry->flags |= (*args[0].from == '^') ? IMA_INMASK : IMA_MASK; break; + case Opt_mode: + ima_log_string(ab, "mode", args[0].from); + if ((strcmp(args[0].from, "IXUGO")) == 0) + entry->flags |= IMA_IXUGO; + else + result = -EINVAL; + break; case Opt_fsmagic: ima_log_string(ab, "fsmagic", args[0].from); @@ -1185,7 +1197,6 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) uid_token = (token == Opt_uid_eq) || (token == Opt_uid_gt) || (token == Opt_uid_lt); - ima_log_string_op(ab, uid_token ? "uid" : "euid", args[0].from, entry->uid_op); @@ -1522,6 +1533,9 @@ int ima_policy_show(struct seq_file *m, void *v) seq_puts(m, " "); } + if (entry->flags & IMA_IXUGO) + seq_puts(m, "mode=IXUGO "); + if (entry->flags & IMA_FSMAGIC) { snprintf(tbuf, sizeof(tbuf), "0x%lx", entry->fsmagic); seq_printf(m, pt(Opt_fsmagic), tbuf); -- 2.7.5