aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/avc.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2012-03-27 11:32:29 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-03-27 11:32:29 -0300
commit50953e0640b3473dcb409d5d0d938c2742c93b0d (patch)
tree3b0dc374e61564fbbd8adff92c8fae16fdeb423a /security/selinux/avc.c
parent[media] update CARDLIST.em28xx (diff)
parentpoll: add poll_requested_events() and poll_does_not_wait() functions (diff)
downloadlinux-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.c70
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);
}
/**