summaryrefslogtreecommitdiff
path: root/security/lsm_audit.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-04-04 21:11:24 +0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-04-04 21:11:24 +0400
commita5149bf3fed59b94207809704b5d06fec337a771 (patch)
tree7a2f0297d35c962040bdd90981376c4b41c40c0f /security/lsm_audit.c
parent3ff8f932bce11fc89e435acb30263a06cb8bd084 (diff)
parentb61c37f57988567c84359645f8202a7c84bc798a (diff)
downloadlinux-a5149bf3fed59b94207809704b5d06fec337a771.tar.xz
Merge branch 'selinux' ("struct common_audit_data" sanitizer)
Merge common_audit_data cleanup patches from Eric Paris. This is really too late, but it's a long-overdue cleanup of the costly wrapper functions for the security layer. The "struct common_audit_data" is used all over in critical paths, allocated and initialized on the stack. And used to be much too large, causing not only unnecessarily big stack frames but the clearing of the (mostly useless) data was also very visible in profiles. As a particular example, in one microbenchmark for just doing "stat()" over files a lot, selinux_inode_permission() used 7% of the CPU time. That's despite the fact that it doesn't actually *do* anything: it is just a helper wrapper function in the selinux security layer. This patch-series shrinks "struct common_audit_data" sufficiently that code generation for these kinds of wrapper functions is improved noticeably, and we spend much less time just initializing data that we will never use. The functions still get called all the time, and it still shows up at 3.5+% in my microbenchmark, but it's quite a bit lower down the list, and much less noticeable. * Emailed patches from Eric Paris <eparis@redhat.com>: lsm_audit: don't specify the audit pre/post callbacks in 'struct common_audit_data' SELinux: do not allocate stack space for AVC data unless needed SELinux: remove avd from slow_avc_audit() SELinux: remove avd from selinux_audit_data LSM: shrink the common_audit_data data union LSM: shrink sizeof LSM specific portion of common_audit_data
Diffstat (limited to 'security/lsm_audit.c')
-rw-r--r--security/lsm_audit.c80
1 files changed, 42 insertions, 38 deletions
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
index 8b8f0902f6e5..90c129b0102f 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -49,8 +49,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb,
if (ih == NULL)
return -EINVAL;
- ad->u.net.v4info.saddr = ih->saddr;
- ad->u.net.v4info.daddr = ih->daddr;
+ ad->u.net->v4info.saddr = ih->saddr;
+ ad->u.net->v4info.daddr = ih->daddr;
if (proto)
*proto = ih->protocol;
@@ -64,8 +64,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb,
if (th == NULL)
break;
- ad->u.net.sport = th->source;
- ad->u.net.dport = th->dest;
+ ad->u.net->sport = th->source;
+ ad->u.net->dport = th->dest;
break;
}
case IPPROTO_UDP: {
@@ -73,8 +73,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb,
if (uh == NULL)
break;
- ad->u.net.sport = uh->source;
- ad->u.net.dport = uh->dest;
+ ad->u.net->sport = uh->source;
+ ad->u.net->dport = uh->dest;
break;
}
case IPPROTO_DCCP: {
@@ -82,16 +82,16 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb,
if (dh == NULL)
break;
- ad->u.net.sport = dh->dccph_sport;
- ad->u.net.dport = dh->dccph_dport;
+ ad->u.net->sport = dh->dccph_sport;
+ ad->u.net->dport = dh->dccph_dport;
break;
}
case IPPROTO_SCTP: {
struct sctphdr *sh = sctp_hdr(skb);
if (sh == NULL)
break;
- ad->u.net.sport = sh->source;
- ad->u.net.dport = sh->dest;
+ ad->u.net->sport = sh->source;
+ ad->u.net->dport = sh->dest;
break;
}
default:
@@ -119,8 +119,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb,
ip6 = ipv6_hdr(skb);
if (ip6 == NULL)
return -EINVAL;
- ad->u.net.v6info.saddr = ip6->saddr;
- ad->u.net.v6info.daddr = ip6->daddr;
+ ad->u.net->v6info.saddr = ip6->saddr;
+ ad->u.net->v6info.daddr = ip6->daddr;
ret = 0;
/* IPv6 can have several extension header before the Transport header
* skip them */
@@ -140,8 +140,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb,
if (th == NULL)
break;
- ad->u.net.sport = th->source;
- ad->u.net.dport = th->dest;
+ ad->u.net->sport = th->source;
+ ad->u.net->dport = th->dest;
break;
}
case IPPROTO_UDP: {
@@ -151,8 +151,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb,
if (uh == NULL)
break;
- ad->u.net.sport = uh->source;
- ad->u.net.dport = uh->dest;
+ ad->u.net->sport = uh->source;
+ ad->u.net->dport = uh->dest;
break;
}
case IPPROTO_DCCP: {
@@ -162,8 +162,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb,
if (dh == NULL)
break;
- ad->u.net.sport = dh->dccph_sport;
- ad->u.net.dport = dh->dccph_dport;
+ ad->u.net->sport = dh->dccph_sport;
+ ad->u.net->dport = dh->dccph_dport;
break;
}
case IPPROTO_SCTP: {
@@ -172,8 +172,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb,
sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph);
if (sh == NULL)
break;
- ad->u.net.sport = sh->source;
- ad->u.net.dport = sh->dest;
+ ad->u.net->sport = sh->source;
+ ad->u.net->dport = sh->dest;
break;
}
default:
@@ -281,8 +281,8 @@ static void dump_common_audit_data(struct audit_buffer *ab,
}
break;
case LSM_AUDIT_DATA_NET:
- if (a->u.net.sk) {
- struct sock *sk = a->u.net.sk;
+ if (a->u.net->sk) {
+ struct sock *sk = a->u.net->sk;
struct unix_sock *u;
int len = 0;
char *p = NULL;
@@ -330,29 +330,29 @@ static void dump_common_audit_data(struct audit_buffer *ab,
}
}
- switch (a->u.net.family) {
+ switch (a->u.net->family) {
case AF_INET:
- print_ipv4_addr(ab, a->u.net.v4info.saddr,
- a->u.net.sport,
+ print_ipv4_addr(ab, a->u.net->v4info.saddr,
+ a->u.net->sport,
"saddr", "src");
- print_ipv4_addr(ab, a->u.net.v4info.daddr,
- a->u.net.dport,
+ print_ipv4_addr(ab, a->u.net->v4info.daddr,
+ a->u.net->dport,
"daddr", "dest");
break;
case AF_INET6:
- print_ipv6_addr(ab, &a->u.net.v6info.saddr,
- a->u.net.sport,
+ print_ipv6_addr(ab, &a->u.net->v6info.saddr,
+ a->u.net->sport,
"saddr", "src");
- print_ipv6_addr(ab, &a->u.net.v6info.daddr,
- a->u.net.dport,
+ print_ipv6_addr(ab, &a->u.net->v6info.daddr,
+ a->u.net->dport,
"daddr", "dest");
break;
}
- if (a->u.net.netif > 0) {
+ if (a->u.net->netif > 0) {
struct net_device *dev;
/* NOTE: we always use init's namespace */
- dev = dev_get_by_index(&init_net, a->u.net.netif);
+ dev = dev_get_by_index(&init_net, a->u.net->netif);
if (dev) {
audit_log_format(ab, " netif=%s", dev->name);
dev_put(dev);
@@ -378,11 +378,15 @@ static void dump_common_audit_data(struct audit_buffer *ab,
/**
* common_lsm_audit - generic LSM auditing function
* @a: auxiliary audit data
+ * @pre_audit: lsm-specific pre-audit callback
+ * @post_audit: lsm-specific post-audit callback
*
* setup the audit buffer for common security information
* uses callback to print LSM specific information
*/
-void common_lsm_audit(struct common_audit_data *a)
+void common_lsm_audit(struct common_audit_data *a,
+ void (*pre_audit)(struct audit_buffer *, void *),
+ void (*post_audit)(struct audit_buffer *, void *))
{
struct audit_buffer *ab;
@@ -394,13 +398,13 @@ void common_lsm_audit(struct common_audit_data *a)
if (ab == NULL)
return;
- if (a->lsm_pre_audit)
- a->lsm_pre_audit(ab, a);
+ if (pre_audit)
+ pre_audit(ab, a);
dump_common_audit_data(ab, a);
- if (a->lsm_post_audit)
- a->lsm_post_audit(ab, a);
+ if (post_audit)
+ post_audit(ab, a);
audit_log_end(ab);
}