Skip to content

Commit 4af4662

Browse files
Mimi ZoharJames Morris
Mimi Zohar
authored and
James Morris
committed
integrity: IMA policy
Support for a user loadable policy through securityfs with support for LSM specific policy data. - free invalid rule in ima_parse_add_rule() Signed-off-by: Mimi Zohar <[email protected]> Acked-by: Serge Hallyn <[email protected]> Signed-off-by: James Morris <[email protected]>
1 parent bab7393 commit 4af4662

File tree

5 files changed

+447
-4
lines changed

5 files changed

+447
-4
lines changed

Documentation/ABI/testing/ima_policy

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
What: security/ima/policy
2+
Date: May 2008
3+
Contact: Mimi Zohar <[email protected]>
4+
Description:
5+
The Trusted Computing Group(TCG) runtime Integrity
6+
Measurement Architecture(IMA) maintains a list of hash
7+
values of executables and other sensitive system files
8+
loaded into the run-time of this system. At runtime,
9+
the policy can be constrained based on LSM specific data.
10+
Policies are loaded into the securityfs file ima/policy
11+
by opening the file, writing the rules one at a time and
12+
then closing the file. The new policy takes effect after
13+
the file ima/policy is closed.
14+
15+
rule format: action [condition ...]
16+
17+
action: measure | dont_measure
18+
condition:= base | lsm
19+
base: [[func=] [mask=] [fsmagic=] [uid=]]
20+
lsm: [[subj_user=] [subj_role=] [subj_type=]
21+
[obj_user=] [obj_role=] [obj_type=]]
22+
23+
base: func:= [BPRM_CHECK][FILE_MMAP][INODE_PERMISSION]
24+
mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC]
25+
fsmagic:= hex value
26+
uid:= decimal value
27+
lsm: are LSM specific
28+
29+
default policy:
30+
# PROC_SUPER_MAGIC
31+
dont_measure fsmagic=0x9fa0
32+
# SYSFS_MAGIC
33+
dont_measure fsmagic=0x62656572
34+
# DEBUGFS_MAGIC
35+
dont_measure fsmagic=0x64626720
36+
# TMPFS_MAGIC
37+
dont_measure fsmagic=0x01021994
38+
# SECURITYFS_MAGIC
39+
dont_measure fsmagic=0x73636673
40+
41+
measure func=BPRM_CHECK
42+
measure func=FILE_MMAP mask=MAY_EXEC
43+
measure func=INODE_PERM mask=MAY_READ uid=0
44+
45+
The default policy measures all executables in bprm_check,
46+
all files mmapped executable in file_mmap, and all files
47+
open for read by root in inode_permission.
48+
49+
Examples of LSM specific definitions:
50+
51+
SELinux:
52+
# SELINUX_MAGIC
53+
dont_measure fsmagic=0xF97CFF8C
54+
55+
dont_measure obj_type=var_log_t
56+
dont_measure obj_type=auditd_log_t
57+
measure subj_user=system_u func=INODE_PERM mask=MAY_READ
58+
measure subj_role=system_r func=INODE_PERM mask=MAY_READ
59+
60+
Smack:
61+
measure subj_user=_ func=INODE_PERM mask=MAY_READ

security/integrity/ima/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,9 @@ config IMA_AUDIT
4747
auditing messages can be enabled with 'ima_audit=1' on
4848
the kernel command line.
4949

50+
config IMA_LSM_RULES
51+
bool
52+
depends on IMA && (SECURITY_SELINUX || SECURITY_SMACK)
53+
default y
54+
help
55+
Disabling this option will disregard LSM based policy rules

security/integrity/ima/ima.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,4 +137,28 @@ enum ima_hooks { PATH_CHECK = 1, FILE_MMAP, BPRM_CHECK };
137137
int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask);
138138
void ima_init_policy(void);
139139
void ima_update_policy(void);
140+
int ima_parse_add_rule(char *);
141+
void ima_delete_rules(void);
142+
143+
/* LSM based policy rules require audit */
144+
#ifdef CONFIG_IMA_LSM_RULES
145+
146+
#define security_filter_rule_init security_audit_rule_init
147+
#define security_filter_rule_match security_audit_rule_match
148+
149+
#else
150+
151+
static inline int security_filter_rule_init(u32 field, u32 op, char *rulestr,
152+
void **lsmrule)
153+
{
154+
return -EINVAL;
155+
}
156+
157+
static inline int security_filter_rule_match(u32 secid, u32 field, u32 op,
158+
void *lsmrule,
159+
struct audit_context *actx)
160+
{
161+
return -EINVAL;
162+
}
163+
#endif /* CONFIG_IMA_LSM_RULES */
140164
#endif

security/integrity/ima/ima_fs.c

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@
1919
#include <linux/seq_file.h>
2020
#include <linux/rculist.h>
2121
#include <linux/rcupdate.h>
22+
#include <linux/parser.h>
2223

2324
#include "ima.h"
2425

26+
static int valid_policy = 1;
2527
#define TMPBUFLEN 12
2628
static ssize_t ima_show_htable_value(char __user *buf, size_t count,
2729
loff_t *ppos, atomic_long_t *val)
@@ -237,11 +239,66 @@ static struct file_operations ima_ascii_measurements_ops = {
237239
.release = seq_release,
238240
};
239241

242+
static ssize_t ima_write_policy(struct file *file, const char __user *buf,
243+
size_t datalen, loff_t *ppos)
244+
{
245+
char *data;
246+
int rc;
247+
248+
if (datalen >= PAGE_SIZE)
249+
return -ENOMEM;
250+
if (*ppos != 0) {
251+
/* No partial writes. */
252+
return -EINVAL;
253+
}
254+
data = kmalloc(datalen + 1, GFP_KERNEL);
255+
if (!data)
256+
return -ENOMEM;
257+
258+
if (copy_from_user(data, buf, datalen)) {
259+
kfree(data);
260+
return -EFAULT;
261+
}
262+
*(data + datalen) = '\0';
263+
rc = ima_parse_add_rule(data);
264+
if (rc < 0) {
265+
datalen = -EINVAL;
266+
valid_policy = 0;
267+
}
268+
269+
kfree(data);
270+
return datalen;
271+
}
272+
240273
static struct dentry *ima_dir;
241274
static struct dentry *binary_runtime_measurements;
242275
static struct dentry *ascii_runtime_measurements;
243276
static struct dentry *runtime_measurements_count;
244277
static struct dentry *violations;
278+
static struct dentry *ima_policy;
279+
280+
/*
281+
* ima_release_policy - start using the new measure policy rules.
282+
*
283+
* Initially, ima_measure points to the default policy rules, now
284+
* point to the new policy rules, and remove the securityfs policy file.
285+
*/
286+
static int ima_release_policy(struct inode *inode, struct file *file)
287+
{
288+
if (!valid_policy) {
289+
ima_delete_rules();
290+
return 0;
291+
}
292+
ima_update_policy();
293+
securityfs_remove(ima_policy);
294+
ima_policy = NULL;
295+
return 0;
296+
}
297+
298+
static struct file_operations ima_measure_policy_ops = {
299+
.write = ima_write_policy,
300+
.release = ima_release_policy
301+
};
245302

246303
int ima_fs_init(void)
247304
{
@@ -276,13 +333,20 @@ int ima_fs_init(void)
276333
if (IS_ERR(violations))
277334
goto out;
278335

279-
return 0;
336+
ima_policy = securityfs_create_file("policy",
337+
S_IRUSR | S_IRGRP | S_IWUSR,
338+
ima_dir, NULL,
339+
&ima_measure_policy_ops);
340+
if (IS_ERR(ima_policy))
341+
goto out;
280342

343+
return 0;
281344
out:
282345
securityfs_remove(runtime_measurements_count);
283346
securityfs_remove(ascii_runtime_measurements);
284347
securityfs_remove(binary_runtime_measurements);
285348
securityfs_remove(ima_dir);
349+
securityfs_remove(ima_policy);
286350
return -1;
287351
}
288352

@@ -293,4 +357,5 @@ void __exit ima_fs_cleanup(void)
293357
securityfs_remove(ascii_runtime_measurements);
294358
securityfs_remove(binary_runtime_measurements);
295359
securityfs_remove(ima_dir);
360+
securityfs_remove(ima_policy);
296361
}

0 commit comments

Comments
 (0)