[PATCH 1/2] ima: add policy support for identifying file execute mode bit

From: Mimi Zohar
Date: Wed Apr 29 2020 - 09:39:17 EST


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