From: Curtis V. <ve...@vp...> - 2015-06-16 03:05:06
|
IMA currently supports the concept of rules based on uid where the rule is based on the uid of the file owner or the uid of the user accessing the file. It is useful to have similar rules based on gid. This patch provides that ability. Signed-off-by: Curtis Veit <ve...@vp...> --- Documentation/ABI/testing/ima_policy | 2 ++ security/integrity/ima/ima_policy.c | 52 ++++++++++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy index d0d0c57..556a827 100644 --- a/Documentation/ABI/testing/ima_policy +++ b/Documentation/ABI/testing/ima_policy @@ -31,7 +31,9 @@ Description: fsmagic:= hex value fsuuid:= file system UUID (e.g 8bcbe394-4f13-4144-be8e-5aa9ea2ce2f6) uid:= decimal value + gid:= decimal value, the group id of the access attempt fowner:=decimal value + fgroup:=decimal value, group id of the file owner lsm: are LSM specific option: appraise_type:= [imasig] diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index d1eefb9..87cccd3 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -27,6 +27,8 @@ #define IMA_UID 0x0008 #define IMA_FOWNER 0x0010 #define IMA_FSUUID 0x0020 +#define IMA_GID 0x0040 +#define IMA_FGROUP 0x0080 #define UNKNOWN 0 #define MEASURE 0x0001 /* same as IMA_MEASURE */ @@ -52,6 +54,8 @@ struct ima_rule_entry { u8 fsuuid[16]; kuid_t uid; kuid_t fowner; + kgid_t gid; + kgid_t fgroup; struct { void *rule; /* LSM file metadata specific */ void *args_p; /* audit value */ @@ -61,7 +65,8 @@ struct ima_rule_entry { /* * Without LSM specific knowledge, the default policy can only be - * written in terms of .action, .func, .mask, .fsmagic, .uid, and .fowner + * written in terms of .action, .func, .mask, .fsmagic, .uid, .fowner + * .gid, and .fgroup. */ /* @@ -192,6 +197,10 @@ static bool ima_match_rules(struct ima_rule_entry *rule, return false; if ((rule->flags & IMA_FOWNER) && !uid_eq(rule->fowner, inode->i_uid)) return false; + if ((rule->flags & IMA_GID) && !gid_eq(rule->gid, cred->gid)) + return false; + if ((rule->flags & IMA_FGROUP) && !gid_eq(rule->fgroup, inode->i_gid)) + return false; for (i = 0; i < MAX_LSM_RULES; i++) { int rc = 0; u32 osid, sid; @@ -374,7 +383,8 @@ enum { 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_uid, Opt_fowner, - Opt_appraise_type, Opt_fsuuid, Opt_permit_directio + Opt_appraise_type, Opt_fsuuid, Opt_permit_directio, + Opt_gid, Opt_fgroup }; static match_table_t policy_tokens = { @@ -395,6 +405,8 @@ static match_table_t policy_tokens = { {Opt_fsuuid, "fsuuid=%s"}, {Opt_uid, "uid=%s"}, {Opt_fowner, "fowner=%s"}, + {Opt_gid, "gid=%s"}, + {Opt_fgroup, "fgroup=%s"}, {Opt_appraise_type, "appraise_type=%s"}, {Opt_permit_directio, "permit_directio"}, {Opt_err, NULL} @@ -442,6 +454,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) entry->uid = INVALID_UID; entry->fowner = INVALID_UID; + entry->gid = INVALID_GID; + entry->fgroup = INVALID_GID; entry->action = UNKNOWN; while ((p = strsep(&rule, " \t")) != NULL) { substring_t args[MAX_OPT_ARGS]; @@ -598,6 +612,40 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) entry->flags |= IMA_FOWNER; } break; + case Opt_gid: + ima_log_string(ab, "gid", args[0].from); + + if (gid_valid(entry->gid)) { + result = -EINVAL; + break; + } + + result = kstrtoul(args[0].from, 10, &lnum); + if (!result) { + entry->gid = make_kgid(current_user_ns(), (gid_t)lnum); + if (!gid_valid(entry->gid) || (((gid_t)lnum) != lnum)) + result = -EINVAL; + else + entry->flags |= IMA_GID; + } + break; + case Opt_fgroup: + ima_log_string(ab, "fgroup", args[0].from); + + if (gid_valid(entry->fgroup)) { + result = -EINVAL; + break; + } + + result = kstrtoul(args[0].from, 10, &lnum); + if (!result) { + entry->fgroup = make_kgid(current_user_ns(), (gid_t)lnum); + if (!gid_valid(entry->fgroup) || (((gid_t)lnum) != lnum)) + result = -EINVAL; + else + entry->flags |= IMA_FGROUP; + } + break; case Opt_obj_user: ima_log_string(ab, "obj_user", args[0].from); result = ima_lsm_rule_init(entry, args, -- 1.9.1 |