Skip to content

Commit b3bddff

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 49afd72 + 24fd03c commit b3bddff

File tree

6 files changed

+112
-25
lines changed

6 files changed

+112
-25
lines changed

Documentation/ABI/testing/ima_policy

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,19 @@ Description:
2020
action: measure | dont_measure | appraise | dont_appraise | audit
2121
condition:= base | lsm [option]
2222
base: [[func=] [mask=] [fsmagic=] [fsuuid=] [uid=]
23-
[fowner]]
23+
[euid=] [fowner=]]
2424
lsm: [[subj_user=] [subj_role=] [subj_type=]
2525
[obj_user=] [obj_role=] [obj_type=]]
2626
option: [[appraise_type=]] [permit_directio]
2727

2828
base: func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK]
2929
[FIRMWARE_CHECK]
30-
mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC]
30+
mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND]
31+
[[^]MAY_EXEC]
3132
fsmagic:= hex value
3233
fsuuid:= file system UUID (e.g 8bcbe394-4f13-4144-be8e-5aa9ea2ce2f6)
3334
uid:= decimal value
35+
euid:= decimal value
3436
fowner:=decimal value
3537
lsm: are LSM specific
3638
option: appraise_type:= [imasig]

Documentation/kernel-parameters.txt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1398,7 +1398,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
13981398
The list of supported hash algorithms is defined
13991399
in crypto/hash_info.h.
14001400

1401-
ima_tcb [IMA]
1401+
ima_policy= [IMA]
1402+
The builtin measurement policy to load during IMA
1403+
setup. Specyfing "tcb" as the value, measures all
1404+
programs exec'd, files mmap'd for exec, and all files
1405+
opened with the read mode bit set by either the
1406+
effective uid (euid=0) or uid=0.
1407+
Format: "tcb"
1408+
1409+
ima_tcb [IMA] Deprecated. Use ima_policy= instead.
14021410
Load a policy which meets the needs of the Trusted
14031411
Computing Base. This means IMA will measure all
14041412
programs exec'd, files mmap'd for exec, and all files

security/integrity/ima/ima.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ void ima_add_violation(struct file *file, const unsigned char *filename,
115115
const char *op, const char *cause);
116116
int ima_init_crypto(void);
117117
void ima_putc(struct seq_file *m, void *data, int datalen);
118-
void ima_print_digest(struct seq_file *m, u8 *digest, int size);
118+
void ima_print_digest(struct seq_file *m, u8 *digest, u32 size);
119119
struct ima_template_desc *ima_template_desc_current(void);
120120
int ima_init_template(void);
121121

security/integrity/ima/ima_fs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,9 @@ static const struct file_operations ima_measurements_ops = {
190190
.release = seq_release,
191191
};
192192

193-
void ima_print_digest(struct seq_file *m, u8 *digest, int size)
193+
void ima_print_digest(struct seq_file *m, u8 *digest, u32 size)
194194
{
195-
int i;
195+
u32 i;
196196

197197
for (i = 0; i < size; i++)
198198
seq_printf(m, "%02x", *(digest + i));

security/integrity/ima/ima_policy.c

Lines changed: 94 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
#define IMA_UID 0x0008
2828
#define IMA_FOWNER 0x0010
2929
#define IMA_FSUUID 0x0020
30+
#define IMA_INMASK 0x0040
31+
#define IMA_EUID 0x0080
3032

3133
#define UNKNOWN 0
3234
#define MEASURE 0x0001 /* same as IMA_MEASURE */
@@ -42,6 +44,8 @@ enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE,
4244
LSM_SUBJ_USER, LSM_SUBJ_ROLE, LSM_SUBJ_TYPE
4345
};
4446

47+
enum policy_types { ORIGINAL_TCB = 1, DEFAULT_TCB };
48+
4549
struct ima_rule_entry {
4650
struct list_head list;
4751
int action;
@@ -70,7 +74,7 @@ struct ima_rule_entry {
7074
* normal users can easily run the machine out of memory simply building
7175
* and running executables.
7276
*/
73-
static struct ima_rule_entry default_rules[] = {
77+
static struct ima_rule_entry dont_measure_rules[] = {
7478
{.action = DONT_MEASURE, .fsmagic = PROC_SUPER_MAGIC, .flags = IMA_FSMAGIC},
7579
{.action = DONT_MEASURE, .fsmagic = SYSFS_MAGIC, .flags = IMA_FSMAGIC},
7680
{.action = DONT_MEASURE, .fsmagic = DEBUGFS_MAGIC, .flags = IMA_FSMAGIC},
@@ -81,13 +85,29 @@ static struct ima_rule_entry default_rules[] = {
8185
{.action = DONT_MEASURE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC},
8286
{.action = DONT_MEASURE, .fsmagic = CGROUP_SUPER_MAGIC,
8387
.flags = IMA_FSMAGIC},
84-
{.action = DONT_MEASURE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC},
88+
{.action = DONT_MEASURE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC}
89+
};
90+
91+
static struct ima_rule_entry original_measurement_rules[] = {
8592
{.action = MEASURE, .func = MMAP_CHECK, .mask = MAY_EXEC,
8693
.flags = IMA_FUNC | IMA_MASK},
8794
{.action = MEASURE, .func = BPRM_CHECK, .mask = MAY_EXEC,
8895
.flags = IMA_FUNC | IMA_MASK},
89-
{.action = MEASURE, .func = FILE_CHECK, .mask = MAY_READ, .uid = GLOBAL_ROOT_UID,
90-
.flags = IMA_FUNC | IMA_MASK | IMA_UID},
96+
{.action = MEASURE, .func = FILE_CHECK, .mask = MAY_READ,
97+
.uid = GLOBAL_ROOT_UID, .flags = IMA_FUNC | IMA_MASK | IMA_UID},
98+
{.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC},
99+
{.action = MEASURE, .func = FIRMWARE_CHECK, .flags = IMA_FUNC},
100+
};
101+
102+
static struct ima_rule_entry default_measurement_rules[] = {
103+
{.action = MEASURE, .func = MMAP_CHECK, .mask = MAY_EXEC,
104+
.flags = IMA_FUNC | IMA_MASK},
105+
{.action = MEASURE, .func = BPRM_CHECK, .mask = MAY_EXEC,
106+
.flags = IMA_FUNC | IMA_MASK},
107+
{.action = MEASURE, .func = FILE_CHECK, .mask = MAY_READ,
108+
.uid = GLOBAL_ROOT_UID, .flags = IMA_FUNC | IMA_INMASK | IMA_EUID},
109+
{.action = MEASURE, .func = FILE_CHECK, .mask = MAY_READ,
110+
.uid = GLOBAL_ROOT_UID, .flags = IMA_FUNC | IMA_INMASK | IMA_UID},
91111
{.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC},
92112
{.action = MEASURE, .func = FIRMWARE_CHECK, .flags = IMA_FUNC},
93113
};
@@ -119,14 +139,29 @@ static struct list_head *ima_rules;
119139

120140
static DEFINE_MUTEX(ima_rules_mutex);
121141

122-
static bool ima_use_tcb __initdata;
142+
static int ima_policy __initdata;
123143
static int __init default_measure_policy_setup(char *str)
124144
{
125-
ima_use_tcb = 1;
145+
if (ima_policy)
146+
return 1;
147+
148+
ima_policy = ORIGINAL_TCB;
126149
return 1;
127150
}
128151
__setup("ima_tcb", default_measure_policy_setup);
129152

153+
static int __init policy_setup(char *str)
154+
{
155+
if (ima_policy)
156+
return 1;
157+
158+
if (strcmp(str, "tcb") == 0)
159+
ima_policy = DEFAULT_TCB;
160+
161+
return 1;
162+
}
163+
__setup("ima_policy=", policy_setup);
164+
130165
static bool ima_use_appraise_tcb __initdata;
131166
static int __init default_appraise_policy_setup(char *str)
132167
{
@@ -186,6 +221,9 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
186221
if ((rule->flags & IMA_MASK) &&
187222
(rule->mask != mask && func != POST_SETATTR))
188223
return false;
224+
if ((rule->flags & IMA_INMASK) &&
225+
(!(rule->mask & mask) && func != POST_SETATTR))
226+
return false;
189227
if ((rule->flags & IMA_FSMAGIC)
190228
&& rule->fsmagic != inode->i_sb->s_magic)
191229
return false;
@@ -194,6 +232,16 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
194232
return false;
195233
if ((rule->flags & IMA_UID) && !uid_eq(rule->uid, cred->uid))
196234
return false;
235+
if (rule->flags & IMA_EUID) {
236+
if (has_capability_noaudit(current, CAP_SETUID)) {
237+
if (!uid_eq(rule->uid, cred->euid)
238+
&& !uid_eq(rule->uid, cred->suid)
239+
&& !uid_eq(rule->uid, cred->uid))
240+
return false;
241+
} else if (!uid_eq(rule->uid, cred->euid))
242+
return false;
243+
}
244+
197245
if ((rule->flags & IMA_FOWNER) && !uid_eq(rule->fowner, inode->i_uid))
198246
return false;
199247
for (i = 0; i < MAX_LSM_RULES; i++) {
@@ -337,13 +385,27 @@ void __init ima_init_policy(void)
337385
{
338386
int i, measure_entries, appraise_entries;
339387

340-
/* if !ima_use_tcb set entries = 0 so we load NO default rules */
341-
measure_entries = ima_use_tcb ? ARRAY_SIZE(default_rules) : 0;
388+
/* if !ima_policy set entries = 0 so we load NO default rules */
389+
measure_entries = ima_policy ? ARRAY_SIZE(dont_measure_rules) : 0;
342390
appraise_entries = ima_use_appraise_tcb ?
343391
ARRAY_SIZE(default_appraise_rules) : 0;
344392

345393
for (i = 0; i < measure_entries; i++)
346-
list_add_tail(&default_rules[i].list, &ima_default_rules);
394+
list_add_tail(&dont_measure_rules[i].list, &ima_default_rules);
395+
396+
switch (ima_policy) {
397+
case ORIGINAL_TCB:
398+
for (i = 0; i < ARRAY_SIZE(original_measurement_rules); i++)
399+
list_add_tail(&original_measurement_rules[i].list,
400+
&ima_default_rules);
401+
break;
402+
case DEFAULT_TCB:
403+
for (i = 0; i < ARRAY_SIZE(default_measurement_rules); i++)
404+
list_add_tail(&default_measurement_rules[i].list,
405+
&ima_default_rules);
406+
default:
407+
break;
408+
}
347409

348410
for (i = 0; i < appraise_entries; i++) {
349411
list_add_tail(&default_appraise_rules[i].list,
@@ -373,7 +435,8 @@ enum {
373435
Opt_audit,
374436
Opt_obj_user, Opt_obj_role, Opt_obj_type,
375437
Opt_subj_user, Opt_subj_role, Opt_subj_type,
376-
Opt_func, Opt_mask, Opt_fsmagic, Opt_uid, Opt_fowner,
438+
Opt_func, Opt_mask, Opt_fsmagic,
439+
Opt_uid, Opt_euid, Opt_fowner,
377440
Opt_appraise_type, Opt_fsuuid, Opt_permit_directio
378441
};
379442

@@ -394,6 +457,7 @@ static match_table_t policy_tokens = {
394457
{Opt_fsmagic, "fsmagic=%s"},
395458
{Opt_fsuuid, "fsuuid=%s"},
396459
{Opt_uid, "uid=%s"},
460+
{Opt_euid, "euid=%s"},
397461
{Opt_fowner, "fowner=%s"},
398462
{Opt_appraise_type, "appraise_type=%s"},
399463
{Opt_permit_directio, "permit_directio"},
@@ -435,6 +499,7 @@ static void ima_log_string(struct audit_buffer *ab, char *key, char *value)
435499
static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
436500
{
437501
struct audit_buffer *ab;
502+
char *from;
438503
char *p;
439504
int result = 0;
440505

@@ -525,18 +590,23 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
525590
if (entry->mask)
526591
result = -EINVAL;
527592

528-
if ((strcmp(args[0].from, "MAY_EXEC")) == 0)
593+
from = args[0].from;
594+
if (*from == '^')
595+
from++;
596+
597+
if ((strcmp(from, "MAY_EXEC")) == 0)
529598
entry->mask = MAY_EXEC;
530-
else if (strcmp(args[0].from, "MAY_WRITE") == 0)
599+
else if (strcmp(from, "MAY_WRITE") == 0)
531600
entry->mask = MAY_WRITE;
532-
else if (strcmp(args[0].from, "MAY_READ") == 0)
601+
else if (strcmp(from, "MAY_READ") == 0)
533602
entry->mask = MAY_READ;
534-
else if (strcmp(args[0].from, "MAY_APPEND") == 0)
603+
else if (strcmp(from, "MAY_APPEND") == 0)
535604
entry->mask = MAY_APPEND;
536605
else
537606
result = -EINVAL;
538607
if (!result)
539-
entry->flags |= IMA_MASK;
608+
entry->flags |= (*args[0].from == '^')
609+
? IMA_INMASK : IMA_MASK;
540610
break;
541611
case Opt_fsmagic:
542612
ima_log_string(ab, "fsmagic", args[0].from);
@@ -566,6 +636,9 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
566636
break;
567637
case Opt_uid:
568638
ima_log_string(ab, "uid", args[0].from);
639+
case Opt_euid:
640+
if (token == Opt_euid)
641+
ima_log_string(ab, "euid", args[0].from);
569642

570643
if (uid_valid(entry->uid)) {
571644
result = -EINVAL;
@@ -574,11 +647,14 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
574647

575648
result = kstrtoul(args[0].from, 10, &lnum);
576649
if (!result) {
577-
entry->uid = make_kuid(current_user_ns(), (uid_t)lnum);
578-
if (!uid_valid(entry->uid) || (((uid_t)lnum) != lnum))
650+
entry->uid = make_kuid(current_user_ns(),
651+
(uid_t) lnum);
652+
if (!uid_valid(entry->uid) ||
653+
(uid_t)lnum != lnum)
579654
result = -EINVAL;
580655
else
581-
entry->flags |= IMA_UID;
656+
entry->flags |= (token == Opt_uid)
657+
? IMA_UID : IMA_EUID;
582658
}
583659
break;
584660
case Opt_fowner:

security/integrity/ima/ima_template_lib.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ static void ima_show_template_data_ascii(struct seq_file *m,
7070
enum data_formats datafmt,
7171
struct ima_field_data *field_data)
7272
{
73-
u8 *buf_ptr = field_data->data, buflen = field_data->len;
73+
u8 *buf_ptr = field_data->data;
74+
u32 buflen = field_data->len;
7475

7576
switch (datafmt) {
7677
case DATA_FMT_DIGEST_WITH_ALGO:

0 commit comments

Comments
 (0)