diff options
author | Eric Paris <eparis@redhat.com> | 2012-04-03 12:37:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-04-03 12:48:40 -0400 |
commit | 3b3b0e4fc15efa507b902d90cea39e496a523c3b (patch) | |
tree | d7b91c21ad6c6f4ac21dd51297b74eec47c61684 /security/selinux/avc.c | |
parent | 95694129b43165911dc4e8a972f0d39ad98d86be (diff) |
LSM: shrink sizeof LSM specific portion of common_audit_data
Linus found that the gigantic size of the common audit data caused a big
perf hit on something as simple as running stat() in a loop. This patch
requires LSMs to declare the LSM specific portion separately rather than
doing it in a union. Thus each LSM can be responsible for shrinking their
portion and don't have to pay a penalty just because other LSMs have a
bigger space requirement.
Signed-off-by: Eric Paris <eparis@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'security/selinux/avc.c')
-rw-r--r-- | security/selinux/avc.c | 34 |
1 files changed, 18 insertions, 16 deletions
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 1a70fa26da72..00f3860c2370 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->denied ? "denied" : "granted"); |
440 | avc_dump_av(ab, ad->selinux_audit_data.tclass, | 440 | avc_dump_av(ab, ad->selinux_audit_data->tclass, |
441 | ad->selinux_audit_data.audited); | 441 | ad->selinux_audit_data->audited); |
442 | audit_log_format(ab, " for "); | 442 | audit_log_format(ab, " for "); |
443 | } | 443 | } |
444 | 444 | ||
@@ -452,9 +452,9 @@ 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->ssid, |
456 | ad->selinux_audit_data.tsid, | 456 | ad->selinux_audit_data->tsid, |
457 | ad->selinux_audit_data.tclass); | 457 | ad->selinux_audit_data->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 */ |
@@ -464,10 +464,12 @@ static noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, | |||
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,}; | ||
467 | 468 | ||
468 | if (!a) { | 469 | if (!a) { |
469 | a = &stack_data; | 470 | a = &stack_data; |
470 | COMMON_AUDIT_DATA_INIT(a, NONE); | 471 | COMMON_AUDIT_DATA_INIT(a, NONE); |
472 | a->selinux_audit_data = &sad; | ||
471 | } | 473 | } |
472 | 474 | ||
473 | /* | 475 | /* |
@@ -481,12 +483,12 @@ static noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, | |||
481 | (flags & MAY_NOT_BLOCK)) | 483 | (flags & MAY_NOT_BLOCK)) |
482 | return -ECHILD; | 484 | return -ECHILD; |
483 | 485 | ||
484 | a->selinux_audit_data.tclass = tclass; | 486 | a->selinux_audit_data->tclass = tclass; |
485 | a->selinux_audit_data.requested = requested; | 487 | a->selinux_audit_data->requested = requested; |
486 | a->selinux_audit_data.ssid = ssid; | 488 | a->selinux_audit_data->ssid = ssid; |
487 | a->selinux_audit_data.tsid = tsid; | 489 | a->selinux_audit_data->tsid = tsid; |
488 | a->selinux_audit_data.audited = audited; | 490 | a->selinux_audit_data->audited = audited; |
489 | a->selinux_audit_data.denied = denied; | 491 | a->selinux_audit_data->denied = denied; |
490 | a->lsm_pre_audit = avc_audit_pre_callback; | 492 | a->lsm_pre_audit = avc_audit_pre_callback; |
491 | a->lsm_post_audit = avc_audit_post_callback; | 493 | a->lsm_post_audit = avc_audit_post_callback; |
492 | common_lsm_audit(a); | 494 | common_lsm_audit(a); |
@@ -523,7 +525,7 @@ inline int avc_audit(u32 ssid, u32 tsid, | |||
523 | if (unlikely(denied)) { | 525 | if (unlikely(denied)) { |
524 | audited = denied & avd->auditdeny; | 526 | audited = denied & avd->auditdeny; |
525 | /* | 527 | /* |
526 | * a->selinux_audit_data.auditdeny is TRICKY! Setting a bit in | 528 | * a->selinux_audit_data->auditdeny is TRICKY! Setting a bit in |
527 | * this field means that ANY denials should NOT be audited if | 529 | * this field means that ANY denials should NOT be audited if |
528 | * the policy contains an explicit dontaudit rule for that | 530 | * the policy contains an explicit dontaudit rule for that |
529 | * permission. Take notice that this is unrelated to the | 531 | * permission. Take notice that this is unrelated to the |
@@ -532,15 +534,15 @@ inline int avc_audit(u32 ssid, u32 tsid, | |||
532 | * | 534 | * |
533 | * denied == READ | 535 | * denied == READ |
534 | * avd.auditdeny & ACCESS == 0 (not set means explicit rule) | 536 | * avd.auditdeny & ACCESS == 0 (not set means explicit rule) |
535 | * selinux_audit_data.auditdeny & ACCESS == 1 | 537 | * selinux_audit_data->auditdeny & ACCESS == 1 |
536 | * | 538 | * |
537 | * We will NOT audit the denial even though the denied | 539 | * We will NOT audit the denial even though the denied |
538 | * permission was READ and the auditdeny checks were for | 540 | * permission was READ and the auditdeny checks were for |
539 | * ACCESS | 541 | * ACCESS |
540 | */ | 542 | */ |
541 | if (a && | 543 | if (a && |
542 | a->selinux_audit_data.auditdeny && | 544 | a->selinux_audit_data->auditdeny && |
543 | !(a->selinux_audit_data.auditdeny & avd->auditdeny)) | 545 | !(a->selinux_audit_data->auditdeny & avd->auditdeny)) |
544 | audited = 0; | 546 | audited = 0; |
545 | } else if (result) | 547 | } else if (result) |
546 | audited = denied = requested; | 548 | audited = denied = requested; |