diff options
Diffstat (limited to 'security/integrity/ima')
-rw-r--r-- | security/integrity/ima/ima_policy.c | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 49998f90e441..c771a2036691 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c | |||
@@ -245,6 +245,9 @@ static int ima_lsm_rule_init(struct ima_measure_rule_entry *entry, | |||
245 | { | 245 | { |
246 | int result; | 246 | int result; |
247 | 247 | ||
248 | if (entry->lsm[lsm_rule].rule) | ||
249 | return -EINVAL; | ||
250 | |||
248 | entry->lsm[lsm_rule].type = audit_type; | 251 | entry->lsm[lsm_rule].type = audit_type; |
249 | result = security_filter_rule_init(entry->lsm[lsm_rule].type, | 252 | result = security_filter_rule_init(entry->lsm[lsm_rule].type, |
250 | Audit_equal, args, | 253 | Audit_equal, args, |
@@ -260,6 +263,7 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry) | |||
260 | 263 | ||
261 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_RULE); | 264 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_RULE); |
262 | 265 | ||
266 | entry->uid = -1; | ||
263 | entry->action = -1; | 267 | entry->action = -1; |
264 | while ((p = strsep(&rule, " ")) != NULL) { | 268 | while ((p = strsep(&rule, " ")) != NULL) { |
265 | substring_t args[MAX_OPT_ARGS]; | 269 | substring_t args[MAX_OPT_ARGS]; |
@@ -274,14 +278,26 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry) | |||
274 | switch (token) { | 278 | switch (token) { |
275 | case Opt_measure: | 279 | case Opt_measure: |
276 | audit_log_format(ab, "%s ", "measure"); | 280 | audit_log_format(ab, "%s ", "measure"); |
281 | |||
282 | if (entry->action != UNKNOWN) | ||
283 | result = -EINVAL; | ||
284 | |||
277 | entry->action = MEASURE; | 285 | entry->action = MEASURE; |
278 | break; | 286 | break; |
279 | case Opt_dont_measure: | 287 | case Opt_dont_measure: |
280 | audit_log_format(ab, "%s ", "dont_measure"); | 288 | audit_log_format(ab, "%s ", "dont_measure"); |
289 | |||
290 | if (entry->action != UNKNOWN) | ||
291 | result = -EINVAL; | ||
292 | |||
281 | entry->action = DONT_MEASURE; | 293 | entry->action = DONT_MEASURE; |
282 | break; | 294 | break; |
283 | case Opt_func: | 295 | case Opt_func: |
284 | audit_log_format(ab, "func=%s ", args[0].from); | 296 | audit_log_format(ab, "func=%s ", args[0].from); |
297 | |||
298 | if (entry->func) | ||
299 | result = -EINVAL; | ||
300 | |||
285 | if (strcmp(args[0].from, "FILE_CHECK") == 0) | 301 | if (strcmp(args[0].from, "FILE_CHECK") == 0) |
286 | entry->func = FILE_CHECK; | 302 | entry->func = FILE_CHECK; |
287 | /* PATH_CHECK is for backwards compat */ | 303 | /* PATH_CHECK is for backwards compat */ |
@@ -298,6 +314,10 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry) | |||
298 | break; | 314 | break; |
299 | case Opt_mask: | 315 | case Opt_mask: |
300 | audit_log_format(ab, "mask=%s ", args[0].from); | 316 | audit_log_format(ab, "mask=%s ", args[0].from); |
317 | |||
318 | if (entry->mask) | ||
319 | result = -EINVAL; | ||
320 | |||
301 | if ((strcmp(args[0].from, "MAY_EXEC")) == 0) | 321 | if ((strcmp(args[0].from, "MAY_EXEC")) == 0) |
302 | entry->mask = MAY_EXEC; | 322 | entry->mask = MAY_EXEC; |
303 | else if (strcmp(args[0].from, "MAY_WRITE") == 0) | 323 | else if (strcmp(args[0].from, "MAY_WRITE") == 0) |
@@ -313,6 +333,12 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry) | |||
313 | break; | 333 | break; |
314 | case Opt_fsmagic: | 334 | case Opt_fsmagic: |
315 | audit_log_format(ab, "fsmagic=%s ", args[0].from); | 335 | audit_log_format(ab, "fsmagic=%s ", args[0].from); |
336 | |||
337 | if (entry->fsmagic) { | ||
338 | result = -EINVAL; | ||
339 | break; | ||
340 | } | ||
341 | |||
316 | result = strict_strtoul(args[0].from, 16, | 342 | result = strict_strtoul(args[0].from, 16, |
317 | &entry->fsmagic); | 343 | &entry->fsmagic); |
318 | if (!result) | 344 | if (!result) |
@@ -320,6 +346,12 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry) | |||
320 | break; | 346 | break; |
321 | case Opt_uid: | 347 | case Opt_uid: |
322 | audit_log_format(ab, "uid=%s ", args[0].from); | 348 | audit_log_format(ab, "uid=%s ", args[0].from); |
349 | |||
350 | if (entry->uid != -1) { | ||
351 | result = -EINVAL; | ||
352 | break; | ||
353 | } | ||
354 | |||
323 | result = strict_strtoul(args[0].from, 10, &lnum); | 355 | result = strict_strtoul(args[0].from, 10, &lnum); |
324 | if (!result) { | 356 | if (!result) { |
325 | entry->uid = (uid_t) lnum; | 357 | entry->uid = (uid_t) lnum; |
@@ -370,7 +402,7 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry) | |||
370 | break; | 402 | break; |
371 | } | 403 | } |
372 | } | 404 | } |
373 | if (entry->action == UNKNOWN) | 405 | if (!result && (entry->action == UNKNOWN)) |
374 | result = -EINVAL; | 406 | result = -EINVAL; |
375 | 407 | ||
376 | audit_log_format(ab, "res=%d", !!result); | 408 | audit_log_format(ab, "res=%d", !!result); |