aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2013-04-16 17:26:51 -0400
committerEric Paris <eparis@redhat.com>2013-04-30 15:31:28 -0400
commitab61d38ed8cf670946d12dc46b9198b521c790ea (patch)
tree742d96692c63be9f9811fcf624f65811f8f6e96c /kernel
parent62062cf8a3a99a933efdac549da380f230dbe982 (diff)
audit: make validity checking generic
We have 2 interfaces to send audit rules. Rather than check validity of things in 2 places make a helper function. Signed-off-by: Eric Paris <eparis@redhat.com>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/auditfilter.c146
1 files changed, 70 insertions, 76 deletions
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 9e666004e0dc..ff6e09d89278 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -310,7 +310,7 @@ static u32 audit_to_op(u32 op)
310 return n; 310 return n;
311} 311}
312 312
313/* check if a field is valid for a given list */ 313/* check if an audit field is valid */
314static int audit_field_valid(struct audit_entry *entry, struct audit_field *f) 314static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
315{ 315{
316 switch(f->type) { 316 switch(f->type) {
@@ -320,6 +320,69 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
320 return -EINVAL; 320 return -EINVAL;
321 break; 321 break;
322 }; 322 };
323
324 switch(f->type) {
325 default:
326 return -EINVAL;
327 case AUDIT_UID:
328 case AUDIT_EUID:
329 case AUDIT_SUID:
330 case AUDIT_FSUID:
331 case AUDIT_LOGINUID:
332 case AUDIT_OBJ_UID:
333 case AUDIT_GID:
334 case AUDIT_EGID:
335 case AUDIT_SGID:
336 case AUDIT_FSGID:
337 case AUDIT_OBJ_GID:
338 case AUDIT_PID:
339 case AUDIT_PERS:
340 case AUDIT_MSGTYPE:
341 case AUDIT_PPID:
342 case AUDIT_DEVMAJOR:
343 case AUDIT_DEVMINOR:
344 case AUDIT_EXIT:
345 case AUDIT_SUCCESS:
346 /* bit ops are only useful on syscall args */
347 if (f->op == Audit_bitmask || f->op == Audit_bittest)
348 return -EINVAL;
349 break;
350 case AUDIT_ARG0:
351 case AUDIT_ARG1:
352 case AUDIT_ARG2:
353 case AUDIT_ARG3:
354 case AUDIT_SUBJ_USER:
355 case AUDIT_SUBJ_ROLE:
356 case AUDIT_SUBJ_TYPE:
357 case AUDIT_SUBJ_SEN:
358 case AUDIT_SUBJ_CLR:
359 case AUDIT_OBJ_USER:
360 case AUDIT_OBJ_ROLE:
361 case AUDIT_OBJ_TYPE:
362 case AUDIT_OBJ_LEV_LOW:
363 case AUDIT_OBJ_LEV_HIGH:
364 case AUDIT_WATCH:
365 case AUDIT_DIR:
366 case AUDIT_FILTERKEY:
367 break;
368 /* arch is only allowed to be = or != */
369 case AUDIT_ARCH:
370 if (f->op != Audit_not_equal && f->op != Audit_equal)
371 return -EINVAL;
372 break;
373 case AUDIT_PERM:
374 if (f->val & ~15)
375 return -EINVAL;
376 break;
377 case AUDIT_FILETYPE:
378 if (f->val & ~S_IFMT)
379 return -EINVAL;
380 break;
381 case AUDIT_FIELD_COMPARE:
382 if (f->val > AUDIT_MAX_FIELD_COMPARE)
383 return -EINVAL;
384 break;
385 };
323 return 0; 386 return 0;
324} 387}
325 388
@@ -361,18 +424,17 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
361 if (f->op == Audit_bad) 424 if (f->op == Audit_bad)
362 goto exit_free; 425 goto exit_free;
363 426
364 switch(f->type) { 427 err = audit_field_valid(entry, f);
365 default: 428 if (err)
366 goto exit_free; 429 goto exit_free;
430
431 err = -EINVAL;
432 switch (f->type) {
367 case AUDIT_UID: 433 case AUDIT_UID:
368 case AUDIT_EUID: 434 case AUDIT_EUID:
369 case AUDIT_SUID: 435 case AUDIT_SUID:
370 case AUDIT_FSUID: 436 case AUDIT_FSUID:
371 case AUDIT_LOGINUID: 437 case AUDIT_LOGINUID:
372 /* bit ops not implemented for uid comparisons */
373 if (f->op == Audit_bitmask || f->op == Audit_bittest)
374 goto exit_free;
375
376 f->uid = make_kuid(current_user_ns(), f->val); 438 f->uid = make_kuid(current_user_ns(), f->val);
377 if (!uid_valid(f->uid)) 439 if (!uid_valid(f->uid))
378 goto exit_free; 440 goto exit_free;
@@ -381,45 +443,13 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
381 case AUDIT_EGID: 443 case AUDIT_EGID:
382 case AUDIT_SGID: 444 case AUDIT_SGID:
383 case AUDIT_FSGID: 445 case AUDIT_FSGID:
384 /* bit ops not implemented for gid comparisons */
385 if (f->op == Audit_bitmask || f->op == Audit_bittest)
386 goto exit_free;
387
388 f->gid = make_kgid(current_user_ns(), f->val); 446 f->gid = make_kgid(current_user_ns(), f->val);
389 if (!gid_valid(f->gid)) 447 if (!gid_valid(f->gid))
390 goto exit_free; 448 goto exit_free;
391 break; 449 break;
392 case AUDIT_PID:
393 case AUDIT_PERS:
394 case AUDIT_MSGTYPE:
395 case AUDIT_PPID:
396 case AUDIT_DEVMAJOR:
397 case AUDIT_DEVMINOR:
398 case AUDIT_EXIT:
399 case AUDIT_SUCCESS:
400 /* bit ops are only useful on syscall args */
401 if (f->op == Audit_bitmask || f->op == Audit_bittest)
402 goto exit_free;
403 break;
404 case AUDIT_ARG0:
405 case AUDIT_ARG1:
406 case AUDIT_ARG2:
407 case AUDIT_ARG3:
408 break;
409 /* arch is only allowed to be = or != */
410 case AUDIT_ARCH: 450 case AUDIT_ARCH:
411 if (f->op != Audit_not_equal && f->op != Audit_equal)
412 goto exit_free;
413 entry->rule.arch_f = f; 451 entry->rule.arch_f = f;
414 break; 452 break;
415 case AUDIT_PERM:
416 if (f->val & ~15)
417 goto exit_free;
418 break;
419 case AUDIT_FILETYPE:
420 if (f->val & ~S_IFMT)
421 goto exit_free;
422 break;
423 case AUDIT_INODE: 453 case AUDIT_INODE:
424 err = audit_to_inode(&entry->rule, f); 454 err = audit_to_inode(&entry->rule, f);
425 if (err) 455 if (err)
@@ -477,18 +507,13 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
477 goto exit_free; 507 goto exit_free;
478 508
479 err = -EINVAL; 509 err = -EINVAL;
480 510 switch (f->type) {
481 switch(f->type) {
482 case AUDIT_UID: 511 case AUDIT_UID:
483 case AUDIT_EUID: 512 case AUDIT_EUID:
484 case AUDIT_SUID: 513 case AUDIT_SUID:
485 case AUDIT_FSUID: 514 case AUDIT_FSUID:
486 case AUDIT_LOGINUID: 515 case AUDIT_LOGINUID:
487 case AUDIT_OBJ_UID: 516 case AUDIT_OBJ_UID:
488 /* bit ops not implemented for uid comparisons */
489 if (f->op == Audit_bitmask || f->op == Audit_bittest)
490 goto exit_free;
491
492 f->uid = make_kuid(current_user_ns(), f->val); 517 f->uid = make_kuid(current_user_ns(), f->val);
493 if (!uid_valid(f->uid)) 518 if (!uid_valid(f->uid))
494 goto exit_free; 519 goto exit_free;
@@ -498,27 +523,10 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
498 case AUDIT_SGID: 523 case AUDIT_SGID:
499 case AUDIT_FSGID: 524 case AUDIT_FSGID:
500 case AUDIT_OBJ_GID: 525 case AUDIT_OBJ_GID:
501 /* bit ops not implemented for gid comparisons */
502 if (f->op == Audit_bitmask || f->op == Audit_bittest)
503 goto exit_free;
504
505 f->gid = make_kgid(current_user_ns(), f->val); 526 f->gid = make_kgid(current_user_ns(), f->val);
506 if (!gid_valid(f->gid)) 527 if (!gid_valid(f->gid))
507 goto exit_free; 528 goto exit_free;
508 break; 529 break;
509 case AUDIT_PID:
510 case AUDIT_PERS:
511 case AUDIT_MSGTYPE:
512 case AUDIT_PPID:
513 case AUDIT_DEVMAJOR:
514 case AUDIT_DEVMINOR:
515 case AUDIT_EXIT:
516 case AUDIT_SUCCESS:
517 case AUDIT_ARG0:
518 case AUDIT_ARG1:
519 case AUDIT_ARG2:
520 case AUDIT_ARG3:
521 break;
522 case AUDIT_ARCH: 530 case AUDIT_ARCH:
523 entry->rule.arch_f = f; 531 entry->rule.arch_f = f;
524 break; 532 break;
@@ -589,20 +597,6 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
589 entry->rule.buflen += f->val; 597 entry->rule.buflen += f->val;
590 entry->rule.filterkey = str; 598 entry->rule.filterkey = str;
591 break; 599 break;
592 case AUDIT_PERM:
593 if (f->val & ~15)
594 goto exit_free;
595 break;
596 case AUDIT_FILETYPE:
597 if (f->val & ~S_IFMT)
598 goto exit_free;
599 break;
600 case AUDIT_FIELD_COMPARE:
601 if (f->val > AUDIT_MAX_FIELD_COMPARE)
602 goto exit_free;
603 break;
604 default:
605 goto exit_free;
606 } 600 }
607 } 601 }
608 602