diff options
author | Mimi Zohar <zohar@linux.vnet.ibm.com> | 2009-02-04 09:07:00 -0500 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2009-02-05 17:05:31 -0500 |
commit | 4af4662fa4a9dc62289c580337ae2506339c4729 (patch) | |
tree | faec95258d2456eb35515f289eb688914ce3b54f /security/integrity/ima/ima_fs.c | |
parent | bab739378758a1e2b2d7ddcee7bc06cf4c591c3c (diff) |
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 <zohar@us.ibm.com>
Acked-by: Serge Hallyn <serue@us.ibm.com>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/integrity/ima/ima_fs.c')
-rw-r--r-- | security/integrity/ima/ima_fs.c | 67 |
1 files changed, 66 insertions, 1 deletions
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index 4f25be768b50..95ef1caa64b5 100644 --- a/security/integrity/ima/ima_fs.c +++ b/security/integrity/ima/ima_fs.c | |||
@@ -19,9 +19,11 @@ | |||
19 | #include <linux/seq_file.h> | 19 | #include <linux/seq_file.h> |
20 | #include <linux/rculist.h> | 20 | #include <linux/rculist.h> |
21 | #include <linux/rcupdate.h> | 21 | #include <linux/rcupdate.h> |
22 | #include <linux/parser.h> | ||
22 | 23 | ||
23 | #include "ima.h" | 24 | #include "ima.h" |
24 | 25 | ||
26 | static int valid_policy = 1; | ||
25 | #define TMPBUFLEN 12 | 27 | #define TMPBUFLEN 12 |
26 | static ssize_t ima_show_htable_value(char __user *buf, size_t count, | 28 | static ssize_t ima_show_htable_value(char __user *buf, size_t count, |
27 | loff_t *ppos, atomic_long_t *val) | 29 | loff_t *ppos, atomic_long_t *val) |
@@ -237,11 +239,66 @@ static struct file_operations ima_ascii_measurements_ops = { | |||
237 | .release = seq_release, | 239 | .release = seq_release, |
238 | }; | 240 | }; |
239 | 241 | ||
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 | |||
240 | static struct dentry *ima_dir; | 273 | static struct dentry *ima_dir; |
241 | static struct dentry *binary_runtime_measurements; | 274 | static struct dentry *binary_runtime_measurements; |
242 | static struct dentry *ascii_runtime_measurements; | 275 | static struct dentry *ascii_runtime_measurements; |
243 | static struct dentry *runtime_measurements_count; | 276 | static struct dentry *runtime_measurements_count; |
244 | static struct dentry *violations; | 277 | 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 | }; | ||
245 | 302 | ||
246 | int ima_fs_init(void) | 303 | int ima_fs_init(void) |
247 | { | 304 | { |
@@ -276,13 +333,20 @@ int ima_fs_init(void) | |||
276 | if (IS_ERR(violations)) | 333 | if (IS_ERR(violations)) |
277 | goto out; | 334 | goto out; |
278 | 335 | ||
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; | ||
280 | 342 | ||
343 | return 0; | ||
281 | out: | 344 | out: |
282 | securityfs_remove(runtime_measurements_count); | 345 | securityfs_remove(runtime_measurements_count); |
283 | securityfs_remove(ascii_runtime_measurements); | 346 | securityfs_remove(ascii_runtime_measurements); |
284 | securityfs_remove(binary_runtime_measurements); | 347 | securityfs_remove(binary_runtime_measurements); |
285 | securityfs_remove(ima_dir); | 348 | securityfs_remove(ima_dir); |
349 | securityfs_remove(ima_policy); | ||
286 | return -1; | 350 | return -1; |
287 | } | 351 | } |
288 | 352 | ||
@@ -293,4 +357,5 @@ void __exit ima_fs_cleanup(void) | |||
293 | securityfs_remove(ascii_runtime_measurements); | 357 | securityfs_remove(ascii_runtime_measurements); |
294 | securityfs_remove(binary_runtime_measurements); | 358 | securityfs_remove(binary_runtime_measurements); |
295 | securityfs_remove(ima_dir); | 359 | securityfs_remove(ima_dir); |
360 | securityfs_remove(ima_policy); | ||
296 | } | 361 | } |