diff options
Diffstat (limited to 'security/selinux/avc.c')
-rw-r--r-- | security/selinux/avc.c | 45 |
1 files changed, 24 insertions, 21 deletions
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 1a70fa26da72..8ee42b2a5f19 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c | |||
@@ -436,9 +436,9 @@ static void avc_audit_pre_callback(struct audit_buffer *ab, void *a) | |||
436 | { | 436 | { |
437 | struct common_audit_data *ad = a; | 437 | struct common_audit_data *ad = a; |
438 | audit_log_format(ab, "avc: %s ", | 438 | audit_log_format(ab, "avc: %s ", |
439 | ad->selinux_audit_data.denied ? "denied" : "granted"); | 439 | ad->selinux_audit_data->slad->denied ? "denied" : "granted"); |
440 | avc_dump_av(ab, ad->selinux_audit_data.tclass, | 440 | avc_dump_av(ab, ad->selinux_audit_data->slad->tclass, |
441 | ad->selinux_audit_data.audited); | 441 | ad->selinux_audit_data->slad->audited); |
442 | audit_log_format(ab, " for "); | 442 | audit_log_format(ab, " for "); |
443 | } | 443 | } |
444 | 444 | ||
@@ -452,22 +452,25 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a) | |||
452 | { | 452 | { |
453 | struct common_audit_data *ad = a; | 453 | struct common_audit_data *ad = a; |
454 | audit_log_format(ab, " "); | 454 | audit_log_format(ab, " "); |
455 | avc_dump_query(ab, ad->selinux_audit_data.ssid, | 455 | avc_dump_query(ab, ad->selinux_audit_data->slad->ssid, |
456 | ad->selinux_audit_data.tsid, | 456 | ad->selinux_audit_data->slad->tsid, |
457 | ad->selinux_audit_data.tclass); | 457 | ad->selinux_audit_data->slad->tclass); |
458 | } | 458 | } |
459 | 459 | ||
460 | /* This is the slow part of avc audit with big stack footprint */ | 460 | /* This is the slow part of avc audit with big stack footprint */ |
461 | static noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, | 461 | static noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, |
462 | u32 requested, u32 audited, u32 denied, | 462 | u32 requested, u32 audited, u32 denied, |
463 | struct av_decision *avd, struct common_audit_data *a, | 463 | struct common_audit_data *a, |
464 | unsigned flags) | 464 | unsigned flags) |
465 | { | 465 | { |
466 | struct common_audit_data stack_data; | 466 | struct common_audit_data stack_data; |
467 | struct selinux_audit_data sad = {0,}; | ||
468 | struct selinux_late_audit_data slad; | ||
467 | 469 | ||
468 | if (!a) { | 470 | if (!a) { |
469 | a = &stack_data; | 471 | a = &stack_data; |
470 | COMMON_AUDIT_DATA_INIT(a, NONE); | 472 | COMMON_AUDIT_DATA_INIT(a, NONE); |
473 | a->selinux_audit_data = &sad; | ||
471 | } | 474 | } |
472 | 475 | ||
473 | /* | 476 | /* |
@@ -481,15 +484,15 @@ static noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, | |||
481 | (flags & MAY_NOT_BLOCK)) | 484 | (flags & MAY_NOT_BLOCK)) |
482 | return -ECHILD; | 485 | return -ECHILD; |
483 | 486 | ||
484 | a->selinux_audit_data.tclass = tclass; | 487 | slad.tclass = tclass; |
485 | a->selinux_audit_data.requested = requested; | 488 | slad.requested = requested; |
486 | a->selinux_audit_data.ssid = ssid; | 489 | slad.ssid = ssid; |
487 | a->selinux_audit_data.tsid = tsid; | 490 | slad.tsid = tsid; |
488 | a->selinux_audit_data.audited = audited; | 491 | slad.audited = audited; |
489 | a->selinux_audit_data.denied = denied; | 492 | slad.denied = denied; |
490 | a->lsm_pre_audit = avc_audit_pre_callback; | 493 | |
491 | a->lsm_post_audit = avc_audit_post_callback; | 494 | a->selinux_audit_data->slad = &slad; |
492 | common_lsm_audit(a); | 495 | common_lsm_audit(a, avc_audit_pre_callback, avc_audit_post_callback); |
493 | return 0; | 496 | return 0; |
494 | } | 497 | } |
495 | 498 | ||
@@ -523,7 +526,7 @@ inline int avc_audit(u32 ssid, u32 tsid, | |||
523 | if (unlikely(denied)) { | 526 | if (unlikely(denied)) { |
524 | audited = denied & avd->auditdeny; | 527 | audited = denied & avd->auditdeny; |
525 | /* | 528 | /* |
526 | * a->selinux_audit_data.auditdeny is TRICKY! Setting a bit in | 529 | * a->selinux_audit_data->auditdeny is TRICKY! Setting a bit in |
527 | * this field means that ANY denials should NOT be audited if | 530 | * this field means that ANY denials should NOT be audited if |
528 | * the policy contains an explicit dontaudit rule for that | 531 | * the policy contains an explicit dontaudit rule for that |
529 | * permission. Take notice that this is unrelated to the | 532 | * permission. Take notice that this is unrelated to the |
@@ -532,15 +535,15 @@ inline int avc_audit(u32 ssid, u32 tsid, | |||
532 | * | 535 | * |
533 | * denied == READ | 536 | * denied == READ |
534 | * avd.auditdeny & ACCESS == 0 (not set means explicit rule) | 537 | * avd.auditdeny & ACCESS == 0 (not set means explicit rule) |
535 | * selinux_audit_data.auditdeny & ACCESS == 1 | 538 | * selinux_audit_data->auditdeny & ACCESS == 1 |
536 | * | 539 | * |
537 | * We will NOT audit the denial even though the denied | 540 | * We will NOT audit the denial even though the denied |
538 | * permission was READ and the auditdeny checks were for | 541 | * permission was READ and the auditdeny checks were for |
539 | * ACCESS | 542 | * ACCESS |
540 | */ | 543 | */ |
541 | if (a && | 544 | if (a && |
542 | a->selinux_audit_data.auditdeny && | 545 | a->selinux_audit_data->auditdeny && |
543 | !(a->selinux_audit_data.auditdeny & avd->auditdeny)) | 546 | !(a->selinux_audit_data->auditdeny & avd->auditdeny)) |
544 | audited = 0; | 547 | audited = 0; |
545 | } else if (result) | 548 | } else if (result) |
546 | audited = denied = requested; | 549 | audited = denied = requested; |
@@ -551,7 +554,7 @@ inline int avc_audit(u32 ssid, u32 tsid, | |||
551 | 554 | ||
552 | return slow_avc_audit(ssid, tsid, tclass, | 555 | return slow_avc_audit(ssid, tsid, tclass, |
553 | requested, audited, denied, | 556 | requested, audited, denied, |
554 | avd, a, flags); | 557 | a, flags); |
555 | } | 558 | } |
556 | 559 | ||
557 | /** | 560 | /** |