Skip to content

Commit f65cc10

Browse files
author
James Morris
committed
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity into next
2 parents 6859e21 + 3dd0c8d commit f65cc10

File tree

2 files changed

+94
-34
lines changed

2 files changed

+94
-34
lines changed

security/integrity/ima/ima_appraise.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,11 @@ int ima_appraise_measurement(enum ima_hooks func,
207207

208208
cause = "missing-hash";
209209
status = INTEGRITY_NOLABEL;
210-
if (opened & FILE_CREATED) {
210+
if (opened & FILE_CREATED)
211211
iint->flags |= IMA_NEW_FILE;
212+
if ((iint->flags & IMA_NEW_FILE) &&
213+
!(iint->flags & IMA_DIGSIG_REQUIRED))
212214
status = INTEGRITY_PASS;
213-
}
214215
goto out;
215216
}
216217

security/integrity/ima/ima_policy.c

Lines changed: 91 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ struct ima_rule_entry {
6464
u8 fsuuid[16];
6565
kuid_t uid;
6666
kuid_t fowner;
67+
bool (*uid_op)(kuid_t, kuid_t); /* Handlers for operators */
68+
bool (*fowner_op)(kuid_t, kuid_t); /* uid_eq(), uid_gt(), uid_lt() */
6769
int pcr;
6870
struct {
6971
void *rule; /* LSM file metadata specific */
@@ -83,7 +85,7 @@ struct ima_rule_entry {
8385
* normal users can easily run the machine out of memory simply building
8486
* and running executables.
8587
*/
86-
static struct ima_rule_entry dont_measure_rules[] = {
88+
static struct ima_rule_entry dont_measure_rules[] __ro_after_init = {
8789
{.action = DONT_MEASURE, .fsmagic = PROC_SUPER_MAGIC, .flags = IMA_FSMAGIC},
8890
{.action = DONT_MEASURE, .fsmagic = SYSFS_MAGIC, .flags = IMA_FSMAGIC},
8991
{.action = DONT_MEASURE, .fsmagic = DEBUGFS_MAGIC, .flags = IMA_FSMAGIC},
@@ -97,32 +99,35 @@ static struct ima_rule_entry dont_measure_rules[] = {
9799
{.action = DONT_MEASURE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC}
98100
};
99101

100-
static struct ima_rule_entry original_measurement_rules[] = {
102+
static struct ima_rule_entry original_measurement_rules[] __ro_after_init = {
101103
{.action = MEASURE, .func = MMAP_CHECK, .mask = MAY_EXEC,
102104
.flags = IMA_FUNC | IMA_MASK},
103105
{.action = MEASURE, .func = BPRM_CHECK, .mask = MAY_EXEC,
104106
.flags = IMA_FUNC | IMA_MASK},
105107
{.action = MEASURE, .func = FILE_CHECK, .mask = MAY_READ,
106-
.uid = GLOBAL_ROOT_UID, .flags = IMA_FUNC | IMA_MASK | IMA_UID},
108+
.uid = GLOBAL_ROOT_UID, .uid_op = &uid_eq,
109+
.flags = IMA_FUNC | IMA_MASK | IMA_UID},
107110
{.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC},
108111
{.action = MEASURE, .func = FIRMWARE_CHECK, .flags = IMA_FUNC},
109112
};
110113

111-
static struct ima_rule_entry default_measurement_rules[] = {
114+
static struct ima_rule_entry default_measurement_rules[] __ro_after_init = {
112115
{.action = MEASURE, .func = MMAP_CHECK, .mask = MAY_EXEC,
113116
.flags = IMA_FUNC | IMA_MASK},
114117
{.action = MEASURE, .func = BPRM_CHECK, .mask = MAY_EXEC,
115118
.flags = IMA_FUNC | IMA_MASK},
116119
{.action = MEASURE, .func = FILE_CHECK, .mask = MAY_READ,
117-
.uid = GLOBAL_ROOT_UID, .flags = IMA_FUNC | IMA_INMASK | IMA_EUID},
120+
.uid = GLOBAL_ROOT_UID, .uid_op = &uid_eq,
121+
.flags = IMA_FUNC | IMA_INMASK | IMA_EUID},
118122
{.action = MEASURE, .func = FILE_CHECK, .mask = MAY_READ,
119-
.uid = GLOBAL_ROOT_UID, .flags = IMA_FUNC | IMA_INMASK | IMA_UID},
123+
.uid = GLOBAL_ROOT_UID, .uid_op = &uid_eq,
124+
.flags = IMA_FUNC | IMA_INMASK | IMA_UID},
120125
{.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC},
121126
{.action = MEASURE, .func = FIRMWARE_CHECK, .flags = IMA_FUNC},
122127
{.action = MEASURE, .func = POLICY_CHECK, .flags = IMA_FUNC},
123128
};
124129

125-
static struct ima_rule_entry default_appraise_rules[] = {
130+
static struct ima_rule_entry default_appraise_rules[] __ro_after_init = {
126131
{.action = DONT_APPRAISE, .fsmagic = PROC_SUPER_MAGIC, .flags = IMA_FSMAGIC},
127132
{.action = DONT_APPRAISE, .fsmagic = SYSFS_MAGIC, .flags = IMA_FSMAGIC},
128133
{.action = DONT_APPRAISE, .fsmagic = DEBUGFS_MAGIC, .flags = IMA_FSMAGIC},
@@ -139,10 +144,11 @@ static struct ima_rule_entry default_appraise_rules[] = {
139144
.flags = IMA_FUNC | IMA_DIGSIG_REQUIRED},
140145
#endif
141146
#ifndef CONFIG_IMA_APPRAISE_SIGNED_INIT
142-
{.action = APPRAISE, .fowner = GLOBAL_ROOT_UID, .flags = IMA_FOWNER},
147+
{.action = APPRAISE, .fowner = GLOBAL_ROOT_UID, .fowner_op = &uid_eq,
148+
.flags = IMA_FOWNER},
143149
#else
144150
/* force signature */
145-
{.action = APPRAISE, .fowner = GLOBAL_ROOT_UID,
151+
{.action = APPRAISE, .fowner = GLOBAL_ROOT_UID, .fowner_op = &uid_eq,
146152
.flags = IMA_FOWNER | IMA_DIGSIG_REQUIRED},
147153
#endif
148154
};
@@ -240,19 +246,20 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
240246
if ((rule->flags & IMA_FSUUID) &&
241247
memcmp(rule->fsuuid, inode->i_sb->s_uuid, sizeof(rule->fsuuid)))
242248
return false;
243-
if ((rule->flags & IMA_UID) && !uid_eq(rule->uid, cred->uid))
249+
if ((rule->flags & IMA_UID) && !rule->uid_op(cred->uid, rule->uid))
244250
return false;
245251
if (rule->flags & IMA_EUID) {
246252
if (has_capability_noaudit(current, CAP_SETUID)) {
247-
if (!uid_eq(rule->uid, cred->euid)
248-
&& !uid_eq(rule->uid, cred->suid)
249-
&& !uid_eq(rule->uid, cred->uid))
253+
if (!rule->uid_op(cred->euid, rule->uid)
254+
&& !rule->uid_op(cred->suid, rule->uid)
255+
&& !rule->uid_op(cred->uid, rule->uid))
250256
return false;
251-
} else if (!uid_eq(rule->uid, cred->euid))
257+
} else if (!rule->uid_op(cred->euid, rule->uid))
252258
return false;
253259
}
254260

255-
if ((rule->flags & IMA_FOWNER) && !uid_eq(rule->fowner, inode->i_uid))
261+
if ((rule->flags & IMA_FOWNER) &&
262+
!rule->fowner_op(inode->i_uid, rule->fowner))
256263
return false;
257264
for (i = 0; i < MAX_LSM_RULES; i++) {
258265
int rc = 0;
@@ -486,7 +493,9 @@ enum {
486493
Opt_obj_user, Opt_obj_role, Opt_obj_type,
487494
Opt_subj_user, Opt_subj_role, Opt_subj_type,
488495
Opt_func, Opt_mask, Opt_fsmagic,
489-
Opt_fsuuid, Opt_uid, Opt_euid, Opt_fowner,
496+
Opt_fsuuid, Opt_uid_eq, Opt_euid_eq, Opt_fowner_eq,
497+
Opt_uid_gt, Opt_euid_gt, Opt_fowner_gt,
498+
Opt_uid_lt, Opt_euid_lt, Opt_fowner_lt,
490499
Opt_appraise_type, Opt_permit_directio,
491500
Opt_pcr
492501
};
@@ -507,9 +516,15 @@ static match_table_t policy_tokens = {
507516
{Opt_mask, "mask=%s"},
508517
{Opt_fsmagic, "fsmagic=%s"},
509518
{Opt_fsuuid, "fsuuid=%s"},
510-
{Opt_uid, "uid=%s"},
511-
{Opt_euid, "euid=%s"},
512-
{Opt_fowner, "fowner=%s"},
519+
{Opt_uid_eq, "uid=%s"},
520+
{Opt_euid_eq, "euid=%s"},
521+
{Opt_fowner_eq, "fowner=%s"},
522+
{Opt_uid_gt, "uid>%s"},
523+
{Opt_euid_gt, "euid>%s"},
524+
{Opt_fowner_gt, "fowner>%s"},
525+
{Opt_uid_lt, "uid<%s"},
526+
{Opt_euid_lt, "euid<%s"},
527+
{Opt_fowner_lt, "fowner<%s"},
513528
{Opt_appraise_type, "appraise_type=%s"},
514529
{Opt_permit_directio, "permit_directio"},
515530
{Opt_pcr, "pcr=%s"},
@@ -541,24 +556,37 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry,
541556
return result;
542557
}
543558

544-
static void ima_log_string(struct audit_buffer *ab, char *key, char *value)
559+
static void ima_log_string_op(struct audit_buffer *ab, char *key, char *value,
560+
bool (*rule_operator)(kuid_t, kuid_t))
545561
{
546-
audit_log_format(ab, "%s=", key);
562+
if (rule_operator == &uid_gt)
563+
audit_log_format(ab, "%s>", key);
564+
else if (rule_operator == &uid_lt)
565+
audit_log_format(ab, "%s<", key);
566+
else
567+
audit_log_format(ab, "%s=", key);
547568
audit_log_untrustedstring(ab, value);
548569
audit_log_format(ab, " ");
549570
}
571+
static void ima_log_string(struct audit_buffer *ab, char *key, char *value)
572+
{
573+
ima_log_string_op(ab, key, value, NULL);
574+
}
550575

551576
static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
552577
{
553578
struct audit_buffer *ab;
554579
char *from;
555580
char *p;
581+
bool uid_token;
556582
int result = 0;
557583

558584
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_RULE);
559585

560586
entry->uid = INVALID_UID;
561587
entry->fowner = INVALID_UID;
588+
entry->uid_op = &uid_eq;
589+
entry->fowner_op = &uid_eq;
562590
entry->action = UNKNOWN;
563591
while ((p = strsep(&rule, " \t")) != NULL) {
564592
substring_t args[MAX_OPT_ARGS];
@@ -694,11 +722,21 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
694722
if (!result)
695723
entry->flags |= IMA_FSUUID;
696724
break;
697-
case Opt_uid:
698-
ima_log_string(ab, "uid", args[0].from);
699-
case Opt_euid:
700-
if (token == Opt_euid)
701-
ima_log_string(ab, "euid", args[0].from);
725+
case Opt_uid_gt:
726+
case Opt_euid_gt:
727+
entry->uid_op = &uid_gt;
728+
case Opt_uid_lt:
729+
case Opt_euid_lt:
730+
if ((token == Opt_uid_lt) || (token == Opt_euid_lt))
731+
entry->uid_op = &uid_lt;
732+
case Opt_uid_eq:
733+
case Opt_euid_eq:
734+
uid_token = (token == Opt_uid_eq) ||
735+
(token == Opt_uid_gt) ||
736+
(token == Opt_uid_lt);
737+
738+
ima_log_string_op(ab, uid_token ? "uid" : "euid",
739+
args[0].from, entry->uid_op);
702740

703741
if (uid_valid(entry->uid)) {
704742
result = -EINVAL;
@@ -713,12 +751,18 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
713751
(uid_t)lnum != lnum)
714752
result = -EINVAL;
715753
else
716-
entry->flags |= (token == Opt_uid)
754+
entry->flags |= uid_token
717755
? IMA_UID : IMA_EUID;
718756
}
719757
break;
720-
case Opt_fowner:
721-
ima_log_string(ab, "fowner", args[0].from);
758+
case Opt_fowner_gt:
759+
entry->fowner_op = &uid_gt;
760+
case Opt_fowner_lt:
761+
if (token == Opt_fowner_lt)
762+
entry->fowner_op = &uid_lt;
763+
case Opt_fowner_eq:
764+
ima_log_string_op(ab, "fowner", args[0].from,
765+
entry->fowner_op);
722766

723767
if (uid_valid(entry->fowner)) {
724768
result = -EINVAL;
@@ -1049,19 +1093,34 @@ int ima_policy_show(struct seq_file *m, void *v)
10491093

10501094
if (entry->flags & IMA_UID) {
10511095
snprintf(tbuf, sizeof(tbuf), "%d", __kuid_val(entry->uid));
1052-
seq_printf(m, pt(Opt_uid), tbuf);
1096+
if (entry->uid_op == &uid_gt)
1097+
seq_printf(m, pt(Opt_uid_gt), tbuf);
1098+
else if (entry->uid_op == &uid_lt)
1099+
seq_printf(m, pt(Opt_uid_lt), tbuf);
1100+
else
1101+
seq_printf(m, pt(Opt_uid_eq), tbuf);
10531102
seq_puts(m, " ");
10541103
}
10551104

10561105
if (entry->flags & IMA_EUID) {
10571106
snprintf(tbuf, sizeof(tbuf), "%d", __kuid_val(entry->uid));
1058-
seq_printf(m, pt(Opt_euid), tbuf);
1107+
if (entry->uid_op == &uid_gt)
1108+
seq_printf(m, pt(Opt_euid_gt), tbuf);
1109+
else if (entry->uid_op == &uid_lt)
1110+
seq_printf(m, pt(Opt_euid_lt), tbuf);
1111+
else
1112+
seq_printf(m, pt(Opt_euid_eq), tbuf);
10591113
seq_puts(m, " ");
10601114
}
10611115

10621116
if (entry->flags & IMA_FOWNER) {
10631117
snprintf(tbuf, sizeof(tbuf), "%d", __kuid_val(entry->fowner));
1064-
seq_printf(m, pt(Opt_fowner), tbuf);
1118+
if (entry->fowner_op == &uid_gt)
1119+
seq_printf(m, pt(Opt_fowner_gt), tbuf);
1120+
else if (entry->fowner_op == &uid_lt)
1121+
seq_printf(m, pt(Opt_fowner_lt), tbuf);
1122+
else
1123+
seq_printf(m, pt(Opt_fowner_eq), tbuf);
10651124
seq_puts(m, " ");
10661125
}
10671126

0 commit comments

Comments
 (0)