diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/integrity/ima/ima.h | 2 | ||||
-rw-r--r-- | security/integrity/ima/ima_fs.c | 38 | ||||
-rw-r--r-- | security/integrity/ima/ima_policy.c | 18 |
3 files changed, 32 insertions, 26 deletions
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 47fb65d1fcbd..16d100d3fc38 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h | |||
@@ -135,7 +135,7 @@ enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK }; | |||
135 | int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask); | 135 | int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask); |
136 | void ima_init_policy(void); | 136 | void ima_init_policy(void); |
137 | void ima_update_policy(void); | 137 | void ima_update_policy(void); |
138 | int ima_parse_add_rule(char *); | 138 | ssize_t ima_parse_add_rule(char *); |
139 | void ima_delete_rules(void); | 139 | void ima_delete_rules(void); |
140 | 140 | ||
141 | /* LSM based policy rules require audit */ | 141 | /* LSM based policy rules require audit */ |
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index 0c72c9c38956..3674a52e1cfb 100644 --- a/security/integrity/ima/ima_fs.c +++ b/security/integrity/ima/ima_fs.c | |||
@@ -243,32 +243,34 @@ static const struct file_operations ima_ascii_measurements_ops = { | |||
243 | static ssize_t ima_write_policy(struct file *file, const char __user *buf, | 243 | static ssize_t ima_write_policy(struct file *file, const char __user *buf, |
244 | size_t datalen, loff_t *ppos) | 244 | size_t datalen, loff_t *ppos) |
245 | { | 245 | { |
246 | char *data; | 246 | char *data = NULL; |
247 | int rc; | 247 | ssize_t result; |
248 | 248 | ||
249 | if (datalen >= PAGE_SIZE) | 249 | if (datalen >= PAGE_SIZE) |
250 | return -ENOMEM; | 250 | datalen = PAGE_SIZE - 1; |
251 | if (*ppos != 0) { | 251 | |
252 | /* No partial writes. */ | 252 | /* No partial writes. */ |
253 | return -EINVAL; | 253 | result = -EINVAL; |
254 | } | 254 | if (*ppos != 0) |
255 | goto out; | ||
256 | |||
257 | result = -ENOMEM; | ||
255 | data = kmalloc(datalen + 1, GFP_KERNEL); | 258 | data = kmalloc(datalen + 1, GFP_KERNEL); |
256 | if (!data) | 259 | if (!data) |
257 | return -ENOMEM; | 260 | goto out; |
258 | 261 | ||
259 | if (copy_from_user(data, buf, datalen)) { | ||
260 | kfree(data); | ||
261 | return -EFAULT; | ||
262 | } | ||
263 | *(data + datalen) = '\0'; | 262 | *(data + datalen) = '\0'; |
264 | rc = ima_parse_add_rule(data); | ||
265 | if (rc < 0) { | ||
266 | datalen = -EINVAL; | ||
267 | valid_policy = 0; | ||
268 | } | ||
269 | 263 | ||
264 | result = -EFAULT; | ||
265 | if (copy_from_user(data, buf, datalen)) | ||
266 | goto out; | ||
267 | |||
268 | result = ima_parse_add_rule(data); | ||
269 | out: | ||
270 | if (result < 0) | ||
271 | valid_policy = 0; | ||
270 | kfree(data); | 272 | kfree(data); |
271 | return datalen; | 273 | return result; |
272 | } | 274 | } |
273 | 275 | ||
274 | static struct dentry *ima_dir; | 276 | static struct dentry *ima_dir; |
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 4759d0f99335..49998f90e441 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c | |||
@@ -261,7 +261,7 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry) | |||
261 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_RULE); | 261 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_RULE); |
262 | 262 | ||
263 | entry->action = -1; | 263 | entry->action = -1; |
264 | while ((p = strsep(&rule, " \n")) != NULL) { | 264 | while ((p = strsep(&rule, " ")) != NULL) { |
265 | substring_t args[MAX_OPT_ARGS]; | 265 | substring_t args[MAX_OPT_ARGS]; |
266 | int token; | 266 | int token; |
267 | unsigned long lnum; | 267 | unsigned long lnum; |
@@ -269,7 +269,7 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry) | |||
269 | if (result < 0) | 269 | if (result < 0) |
270 | break; | 270 | break; |
271 | if (!*p) | 271 | if (!*p) |
272 | continue; | 272 | break; |
273 | token = match_token(p, policy_tokens, args); | 273 | token = match_token(p, policy_tokens, args); |
274 | switch (token) { | 274 | switch (token) { |
275 | case Opt_measure: | 275 | case Opt_measure: |
@@ -373,7 +373,7 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry) | |||
373 | if (entry->action == UNKNOWN) | 373 | if (entry->action == UNKNOWN) |
374 | result = -EINVAL; | 374 | result = -EINVAL; |
375 | 375 | ||
376 | audit_log_format(ab, "res=%d", !result ? 0 : 1); | 376 | audit_log_format(ab, "res=%d", !!result); |
377 | audit_log_end(ab); | 377 | audit_log_end(ab); |
378 | return result; | 378 | return result; |
379 | } | 379 | } |
@@ -383,13 +383,14 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry) | |||
383 | * @rule - ima measurement policy rule | 383 | * @rule - ima measurement policy rule |
384 | * | 384 | * |
385 | * Uses a mutex to protect the policy list from multiple concurrent writers. | 385 | * Uses a mutex to protect the policy list from multiple concurrent writers. |
386 | * Returns 0 on success, an error code on failure. | 386 | * Returns the length of the rule parsed, an error code on failure |
387 | */ | 387 | */ |
388 | int ima_parse_add_rule(char *rule) | 388 | ssize_t ima_parse_add_rule(char *rule) |
389 | { | 389 | { |
390 | const char *op = "update_policy"; | 390 | const char *op = "update_policy"; |
391 | char *p; | ||
391 | struct ima_measure_rule_entry *entry; | 392 | struct ima_measure_rule_entry *entry; |
392 | int result = 0; | 393 | ssize_t result, len; |
393 | int audit_info = 0; | 394 | int audit_info = 0; |
394 | 395 | ||
395 | /* Prevent installed policy from changing */ | 396 | /* Prevent installed policy from changing */ |
@@ -409,8 +410,11 @@ int ima_parse_add_rule(char *rule) | |||
409 | 410 | ||
410 | INIT_LIST_HEAD(&entry->list); | 411 | INIT_LIST_HEAD(&entry->list); |
411 | 412 | ||
412 | result = ima_parse_rule(rule, entry); | 413 | p = strsep(&rule, "\n"); |
414 | len = strlen(p) + 1; | ||
415 | result = ima_parse_rule(p, entry); | ||
413 | if (!result) { | 416 | if (!result) { |
417 | result = len; | ||
414 | mutex_lock(&ima_measure_mutex); | 418 | mutex_lock(&ima_measure_mutex); |
415 | list_add_tail(&entry->list, &measure_policy_rules); | 419 | list_add_tail(&entry->list, &measure_policy_rules); |
416 | mutex_unlock(&ima_measure_mutex); | 420 | mutex_unlock(&ima_measure_mutex); |