Commit be940d62 authored by James Morris's avatar James Morris

Revert "SELinux: Convert avc_audit to use lsm_audit.h"

This reverts commit 8113a8d8.

The patch causes a stack overflow on my system during boot.
Signed-off-by: default avatarJames Morris <jmorris@namei.org>
parent b3a633c8
......@@ -16,7 +16,9 @@ obj-$(CONFIG_SECURITYFS) += inode.o
# Must precede capability.o in order to stack properly.
obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o
obj-$(CONFIG_AUDIT) += lsm_audit.o
ifeq ($(CONFIG_AUDIT),y)
obj-$(CONFIG_SECURITY_SMACK) += lsm_audit.o
endif
obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/built-in.o
obj-$(CONFIG_SECURITY_ROOTPLUG) += root_plug.o
obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o
......
......@@ -492,50 +492,23 @@ static struct avc_node *avc_insert(u32 ssid, u32 tsid, u16 tclass, struct av_dec
return node;
}
/**
* avc_audit_pre_callback - SELinux specific information
* will be called by generic audit code
* @ab: the audit buffer
* @a: audit_data
*/
static void avc_audit_pre_callback(struct audit_buffer *ab, void *a)
static inline void avc_print_ipv6_addr(struct audit_buffer *ab,
struct in6_addr *addr, __be16 port,
char *name1, char *name2)
{
struct common_audit_data *ad = a;
struct av_decision *avd = ad->selinux_audit_data.avd;
u32 requested = ad->selinux_audit_data.requested;
int result = ad->selinux_audit_data.result;
u32 denied, audited;
denied = requested & ~avd->allowed;
if (denied) {
audited = denied;
if (!(audited & avd->auditdeny))
return;
} else if (result) {
audited = denied = requested;
} else {
audited = requested;
if (!(audited & avd->auditallow))
return;
}
audit_log_format(ab, "avc: %s ", denied ? "denied" : "granted");
avc_dump_av(ab, ad->selinux_audit_data.tclass,
ad->selinux_audit_data.audited);
audit_log_format(ab, " for ");
if (!ipv6_addr_any(addr))
audit_log_format(ab, " %s=%pI6", name1, addr);
if (port)
audit_log_format(ab, " %s=%d", name2, ntohs(port));
}
/**
* avc_audit_post_callback - SELinux specific information
* will be called by generic audit code
* @ab: the audit buffer
* @a: audit_data
*/
static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
static inline void avc_print_ipv4_addr(struct audit_buffer *ab, __be32 addr,
__be16 port, char *name1, char *name2)
{
struct common_audit_data *ad = a;
audit_log_format(ab, " ");
avc_dump_query(ab, ad->selinux_audit_data.ssid,
ad->selinux_audit_data.tsid,
ad->selinux_audit_data.tclass);
if (addr)
audit_log_format(ab, " %s=%pI4", name1, &addr);
if (port)
audit_log_format(ab, " %s=%d", name2, ntohs(port));
}
/**
......@@ -559,14 +532,163 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
*/
void avc_audit(u32 ssid, u32 tsid,
u16 tclass, u32 requested,
struct av_decision *avd, int result, struct common_audit_data *a)
struct av_decision *avd, int result, struct avc_audit_data *a)
{
a->selinux_audit_data.avd = avd;
a->selinux_audit_data.tclass = tclass;
a->selinux_audit_data.requested = requested;
a->lsm_pre_audit = avc_audit_pre_callback;
a->lsm_post_audit = avc_audit_post_callback;
common_lsm_audit(a);
struct task_struct *tsk = current;
struct inode *inode = NULL;
u32 denied, audited;
struct audit_buffer *ab;
denied = requested & ~avd->allowed;
if (denied) {
audited = denied;
if (!(audited & avd->auditdeny))
return;
} else if (result) {
audited = denied = requested;
} else {
audited = requested;
if (!(audited & avd->auditallow))
return;
}
ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_AVC);
if (!ab)
return; /* audit_panic has been called */
audit_log_format(ab, "avc: %s ", denied ? "denied" : "granted");
avc_dump_av(ab, tclass, audited);
audit_log_format(ab, " for ");
if (a && a->tsk)
tsk = a->tsk;
if (tsk && tsk->pid) {
audit_log_format(ab, " pid=%d comm=", tsk->pid);
audit_log_untrustedstring(ab, tsk->comm);
}
if (a) {
switch (a->type) {
case AVC_AUDIT_DATA_IPC:
audit_log_format(ab, " key=%d", a->u.ipc_id);
break;
case AVC_AUDIT_DATA_CAP:
audit_log_format(ab, " capability=%d", a->u.cap);
break;
case AVC_AUDIT_DATA_FS:
if (a->u.fs.path.dentry) {
struct dentry *dentry = a->u.fs.path.dentry;
if (a->u.fs.path.mnt) {
audit_log_d_path(ab, "path=",
&a->u.fs.path);
} else {
audit_log_format(ab, " name=");
audit_log_untrustedstring(ab, dentry->d_name.name);
}
inode = dentry->d_inode;
} else if (a->u.fs.inode) {
struct dentry *dentry;
inode = a->u.fs.inode;
dentry = d_find_alias(inode);
if (dentry) {
audit_log_format(ab, " name=");
audit_log_untrustedstring(ab, dentry->d_name.name);
dput(dentry);
}
}
if (inode)
audit_log_format(ab, " dev=%s ino=%lu",
inode->i_sb->s_id,
inode->i_ino);
break;
case AVC_AUDIT_DATA_NET:
if (a->u.net.sk) {
struct sock *sk = a->u.net.sk;
struct unix_sock *u;
int len = 0;
char *p = NULL;
switch (sk->sk_family) {
case AF_INET: {
struct inet_sock *inet = inet_sk(sk);
avc_print_ipv4_addr(ab, inet->rcv_saddr,
inet->sport,
"laddr", "lport");
avc_print_ipv4_addr(ab, inet->daddr,
inet->dport,
"faddr", "fport");
break;
}
case AF_INET6: {
struct inet_sock *inet = inet_sk(sk);
struct ipv6_pinfo *inet6 = inet6_sk(sk);
avc_print_ipv6_addr(ab, &inet6->rcv_saddr,
inet->sport,
"laddr", "lport");
avc_print_ipv6_addr(ab, &inet6->daddr,
inet->dport,
"faddr", "fport");
break;
}
case AF_UNIX:
u = unix_sk(sk);
if (u->dentry) {
struct path path = {
.dentry = u->dentry,
.mnt = u->mnt
};
audit_log_d_path(ab, "path=",
&path);
break;
}
if (!u->addr)
break;
len = u->addr->len-sizeof(short);
p = &u->addr->name->sun_path[0];
audit_log_format(ab, " path=");
if (*p)
audit_log_untrustedstring(ab, p);
else
audit_log_n_hex(ab, p, len);
break;
}
}
switch (a->u.net.family) {
case AF_INET:
avc_print_ipv4_addr(ab, a->u.net.v4info.saddr,
a->u.net.sport,
"saddr", "src");
avc_print_ipv4_addr(ab, a->u.net.v4info.daddr,
a->u.net.dport,
"daddr", "dest");
break;
case AF_INET6:
avc_print_ipv6_addr(ab, &a->u.net.v6info.saddr,
a->u.net.sport,
"saddr", "src");
avc_print_ipv6_addr(ab, &a->u.net.v6info.daddr,
a->u.net.dport,
"daddr", "dest");
break;
}
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);
if (dev) {
audit_log_format(ab, " netif=%s",
dev->name);
dev_put(dev);
}
}
break;
}
}
audit_log_format(ab, " ");
avc_dump_query(ab, ssid, tsid, tclass);
audit_log_end(ab);
}
/**
......@@ -834,7 +956,7 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
* another -errno upon other errors.
*/
int avc_has_perm(u32 ssid, u32 tsid, u16 tclass,
u32 requested, struct common_audit_data *auditdata)
u32 requested, struct avc_audit_data *auditdata)
{
struct av_decision avd;
int rc;
......
This diff is collapsed.
......@@ -13,7 +13,6 @@
#include <linux/spinlock.h>
#include <linux/init.h>
#include <linux/audit.h>
#include <linux/lsm_audit.h>
#include <linux/in6.h>
#include <linux/path.h>
#include <asm/system.h>
......@@ -37,6 +36,48 @@ struct inode;
struct sock;
struct sk_buff;
/* Auxiliary data to use in generating the audit record. */
struct avc_audit_data {
char type;
#define AVC_AUDIT_DATA_FS 1
#define AVC_AUDIT_DATA_NET 2
#define AVC_AUDIT_DATA_CAP 3
#define AVC_AUDIT_DATA_IPC 4
struct task_struct *tsk;
union {
struct {
struct path path;
struct inode *inode;
} fs;
struct {
int netif;
struct sock *sk;
u16 family;
__be16 dport;
__be16 sport;
union {
struct {
__be32 daddr;
__be32 saddr;
} v4;
struct {
struct in6_addr daddr;
struct in6_addr saddr;
} v6;
} fam;
} net;
int cap;
int ipc_id;
} u;
};
#define v4info fam.v4
#define v6info fam.v6
/* Initialize an AVC audit data structure. */
#define AVC_AUDIT_DATA_INIT(_d,_t) \
{ memset((_d), 0, sizeof(struct avc_audit_data)); (_d)->type = AVC_AUDIT_DATA_##_t; }
/*
* AVC statistics
*/
......@@ -57,9 +98,7 @@ void __init avc_init(void);
void avc_audit(u32 ssid, u32 tsid,
u16 tclass, u32 requested,
struct av_decision *avd,
int result,
struct common_audit_data *a);
struct av_decision *avd, int result, struct avc_audit_data *auditdata);
#define AVC_STRICT 1 /* Ignore permissive mode. */
int avc_has_perm_noaudit(u32 ssid, u32 tsid,
......@@ -69,7 +108,7 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
int avc_has_perm(u32 ssid, u32 tsid,
u16 tclass, u32 requested,
struct common_audit_data *auditdata);
struct avc_audit_data *auditdata);
u32 avc_policy_seqno(void);
......
......@@ -59,7 +59,7 @@ int selinux_netlbl_socket_post_create(struct sock *sk, u16 family);
int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
struct sk_buff *skb,
u16 family,
struct common_audit_data *ad);
struct avc_audit_data *ad);
int selinux_netlbl_socket_setsockopt(struct socket *sock,
int level,
int optname);
......@@ -129,7 +129,7 @@ static inline int selinux_netlbl_socket_post_create(struct sock *sk,
static inline int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
struct sk_buff *skb,
u16 family,
struct common_audit_data *ad)
struct avc_audit_data *ad)
{
return 0;
}
......
......@@ -41,9 +41,9 @@ static inline int selinux_xfrm_enabled(void)
}
int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb,
struct common_audit_data *ad);
struct avc_audit_data *ad);
int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb,
struct common_audit_data *ad, u8 proto);
struct avc_audit_data *ad, u8 proto);
int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall);
static inline void selinux_xfrm_notify_policyload(void)
......@@ -57,13 +57,13 @@ static inline int selinux_xfrm_enabled(void)
}
static inline int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb,
struct common_audit_data *ad)
struct avc_audit_data *ad)
{
return 0;
}
static inline int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb,
struct common_audit_data *ad, u8 proto)
struct avc_audit_data *ad, u8 proto)
{
return 0;
}
......
......@@ -342,7 +342,7 @@ int selinux_netlbl_socket_post_create(struct sock *sk, u16 family)
int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
struct sk_buff *skb,
u16 family,
struct common_audit_data *ad)
struct avc_audit_data *ad)
{
int rc;
u32 nlbl_sid;
......
......@@ -401,7 +401,7 @@ int selinux_xfrm_state_delete(struct xfrm_state *x)
* gone thru the IPSec process.
*/
int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb,
struct common_audit_data *ad)
struct avc_audit_data *ad)
{
int i, rc = 0;
struct sec_path *sp;
......@@ -442,7 +442,7 @@ int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb,
* checked in the selinux_xfrm_state_pol_flow_match hook above.
*/
int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb,
struct common_audit_data *ad, u8 proto)
struct avc_audit_data *ad, u8 proto)
{
struct dst_entry *dst;
int rc = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment