diff options
| author | 2012-03-27 11:32:29 -0300 | |
|---|---|---|
| committer | 2012-03-27 11:32:29 -0300 | |
| commit | 50953e0640b3473dcb409d5d0d938c2742c93b0d (patch) | |
| tree | 3b0dc374e61564fbbd8adff92c8fae16fdeb423a /security/selinux/avc.c | |
| parent | [media] update CARDLIST.em28xx (diff) | |
| parent | poll: add poll_requested_events() and poll_does_not_wait() functions (diff) | |
| download | linux-dev-50953e0640b3473dcb409d5d0d938c2742c93b0d.tar.xz linux-dev-50953e0640b3473dcb409d5d0d938c2742c93b0d.zip | |
Merge branch 'poll' into staging/for_v3.4
* poll: (5970 commits)
poll: add poll_requested_events() and poll_does_not_wait() functions
crc32: select an algorithm via Kconfig
crc32: add self-test code for crc32c
crypto: crc32c should use library implementation
crc32: bolt on crc32c
crc32: add note about this patchset to crc32.c
crc32: optimize loop counter for x86
crc32: add slice-by-8 algorithm to existing code
crc32: make CRC_*_BITS definition correspond to actual bit counts
crc32: fix mixing of endian-specific types
crc32: miscellaneous cleanups
crc32: simplify unit test code
crc32: move long comment about crc32 fundamentals to Documentation/
crc32: remove two instances of trailing whitespaces
checkpatch: check for quoted strings broken across lines
checkpatch: whitespace - add/remove blank lines
checkpatch: warn on use of yield()
checkpatch: add --strict tests for braces, comments and casts
checkpatch: add [] to type extensions
checkpatch: high precedence operators do not require additional parentheses in #defines
...
Diffstat (limited to 'security/selinux/avc.c')
| -rw-r--r-- | security/selinux/avc.c | 70 |
1 files changed, 41 insertions, 29 deletions
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index dca1c22d9276..6989472d0957 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -457,6 +457,42 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a) ad->selinux_audit_data.tclass); } +/* This is the slow part of avc audit with big stack footprint */ +static noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, + u32 requested, u32 audited, u32 denied, + struct av_decision *avd, struct common_audit_data *a, + unsigned flags) +{ + struct common_audit_data stack_data; + + if (!a) { + a = &stack_data; + COMMON_AUDIT_DATA_INIT(a, NONE); + } + + /* + * When in a RCU walk do the audit on the RCU retry. This is because + * the collection of the dname in an inode audit message is not RCU + * safe. Note this may drop some audits when the situation changes + * during retry. However this is logically just as if the operation + * happened a little later. + */ + if ((a->type == LSM_AUDIT_DATA_INODE) && + (flags & MAY_NOT_BLOCK)) + return -ECHILD; + + a->selinux_audit_data.tclass = tclass; + a->selinux_audit_data.requested = requested; + a->selinux_audit_data.ssid = ssid; + a->selinux_audit_data.tsid = tsid; + a->selinux_audit_data.audited = audited; + a->selinux_audit_data.denied = denied; + a->lsm_pre_audit = avc_audit_pre_callback; + a->lsm_post_audit = avc_audit_post_callback; + common_lsm_audit(a); + return 0; +} + /** * avc_audit - Audit the granting or denial of permissions. * @ssid: source security identifier @@ -482,10 +518,9 @@ int avc_audit(u32 ssid, u32 tsid, struct av_decision *avd, int result, struct common_audit_data *a, unsigned flags) { - struct common_audit_data stack_data; u32 denied, audited; denied = requested & ~avd->allowed; - if (denied) { + if (unlikely(denied)) { audited = denied & avd->auditdeny; /* * a->selinux_audit_data.auditdeny is TRICKY! Setting a bit in @@ -511,35 +546,12 @@ int avc_audit(u32 ssid, u32 tsid, audited = denied = requested; else audited = requested & avd->auditallow; - if (!audited) + if (likely(!audited)) return 0; - if (!a) { - a = &stack_data; - COMMON_AUDIT_DATA_INIT(a, NONE); - } - - /* - * When in a RCU walk do the audit on the RCU retry. This is because - * the collection of the dname in an inode audit message is not RCU - * safe. Note this may drop some audits when the situation changes - * during retry. However this is logically just as if the operation - * happened a little later. - */ - if ((a->type == LSM_AUDIT_DATA_INODE) && - (flags & MAY_NOT_BLOCK)) - return -ECHILD; - - a->selinux_audit_data.tclass = tclass; - a->selinux_audit_data.requested = requested; - a->selinux_audit_data.ssid = ssid; - a->selinux_audit_data.tsid = tsid; - a->selinux_audit_data.audited = audited; - a->selinux_audit_data.denied = denied; - a->lsm_pre_audit = avc_audit_pre_callback; - a->lsm_post_audit = avc_audit_post_callback; - common_lsm_audit(a); - return 0; + return slow_avc_audit(ssid, tsid, tclass, + requested, audited, denied, + avd, a, flags); } /** |
