aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/integrity/ima/ima.h2
-rw-r--r--security/integrity/ima/ima_fs.c38
-rw-r--r--security/integrity/ima/ima_policy.c18
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 };
135int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask); 135int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask);
136void ima_init_policy(void); 136void ima_init_policy(void);
137void ima_update_policy(void); 137void ima_update_policy(void);
138int ima_parse_add_rule(char *); 138ssize_t ima_parse_add_rule(char *);
139void ima_delete_rules(void); 139void 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 = {
243static ssize_t ima_write_policy(struct file *file, const char __user *buf, 243static 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);
269out:
270 if (result < 0)
271 valid_policy = 0;
270 kfree(data); 272 kfree(data);
271 return datalen; 273 return result;
272} 274}
273 275
274static struct dentry *ima_dir; 276static 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 */
388int ima_parse_add_rule(char *rule) 388ssize_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);