Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be940d62 authored by James Morris's avatar James Morris
Browse files

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
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -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
+170 −48
Original line number Diff line number Diff line
@@ -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;
+71 −71
Original line number Diff line number Diff line
@@ -1478,14 +1478,14 @@ static int task_has_capability(struct task_struct *tsk,
			       const struct cred *cred,
			       int cap, int audit)
{
	struct common_audit_data ad;
	struct avc_audit_data ad;
	struct av_decision avd;
	u16 sclass;
	u32 sid = cred_sid(cred);
	u32 av = CAP_TO_MASK(cap);
	int rc;

	COMMON_AUDIT_DATA_INIT(&ad, CAP);
	AVC_AUDIT_DATA_INIT(&ad, CAP);
	ad.tsk = tsk;
	ad.u.cap = cap;

@@ -1524,10 +1524,10 @@ static int task_has_system(struct task_struct *tsk,
static int inode_has_perm(const struct cred *cred,
			  struct inode *inode,
			  u32 perms,
			  struct common_audit_data *adp)
			  struct avc_audit_data *adp)
{
	struct inode_security_struct *isec;
	struct common_audit_data ad;
	struct avc_audit_data ad;
	u32 sid;

	if (unlikely(IS_PRIVATE(inode)))
@@ -1538,7 +1538,7 @@ static int inode_has_perm(const struct cred *cred,

	if (!adp) {
		adp = &ad;
		COMMON_AUDIT_DATA_INIT(&ad, FS);
		AVC_AUDIT_DATA_INIT(&ad, FS);
		ad.u.fs.inode = inode;
	}

@@ -1554,9 +1554,9 @@ static inline int dentry_has_perm(const struct cred *cred,
				  u32 av)
{
	struct inode *inode = dentry->d_inode;
	struct common_audit_data ad;
	struct avc_audit_data ad;

	COMMON_AUDIT_DATA_INIT(&ad, FS);
	AVC_AUDIT_DATA_INIT(&ad, FS);
	ad.u.fs.path.mnt = mnt;
	ad.u.fs.path.dentry = dentry;
	return inode_has_perm(cred, inode, av, &ad);
@@ -1576,11 +1576,11 @@ static int file_has_perm(const struct cred *cred,
{
	struct file_security_struct *fsec = file->f_security;
	struct inode *inode = file->f_path.dentry->d_inode;
	struct common_audit_data ad;
	struct avc_audit_data ad;
	u32 sid = cred_sid(cred);
	int rc;

	COMMON_AUDIT_DATA_INIT(&ad, FS);
	AVC_AUDIT_DATA_INIT(&ad, FS);
	ad.u.fs.path = file->f_path;

	if (sid != fsec->sid) {
@@ -1611,7 +1611,7 @@ static int may_create(struct inode *dir,
	struct inode_security_struct *dsec;
	struct superblock_security_struct *sbsec;
	u32 sid, newsid;
	struct common_audit_data ad;
	struct avc_audit_data ad;
	int rc;

	dsec = dir->i_security;
@@ -1620,7 +1620,7 @@ static int may_create(struct inode *dir,
	sid = tsec->sid;
	newsid = tsec->create_sid;

	COMMON_AUDIT_DATA_INIT(&ad, FS);
	AVC_AUDIT_DATA_INIT(&ad, FS);
	ad.u.fs.path.dentry = dentry;

	rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR,
@@ -1664,7 +1664,7 @@ static int may_link(struct inode *dir,

{
	struct inode_security_struct *dsec, *isec;
	struct common_audit_data ad;
	struct avc_audit_data ad;
	u32 sid = current_sid();
	u32 av;
	int rc;
@@ -1672,7 +1672,7 @@ static int may_link(struct inode *dir,
	dsec = dir->i_security;
	isec = dentry->d_inode->i_security;

	COMMON_AUDIT_DATA_INIT(&ad, FS);
	AVC_AUDIT_DATA_INIT(&ad, FS);
	ad.u.fs.path.dentry = dentry;

	av = DIR__SEARCH;
@@ -1707,7 +1707,7 @@ static inline int may_rename(struct inode *old_dir,
			     struct dentry *new_dentry)
{
	struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec;
	struct common_audit_data ad;
	struct avc_audit_data ad;
	u32 sid = current_sid();
	u32 av;
	int old_is_dir, new_is_dir;
@@ -1718,7 +1718,7 @@ static inline int may_rename(struct inode *old_dir,
	old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
	new_dsec = new_dir->i_security;

	COMMON_AUDIT_DATA_INIT(&ad, FS);
	AVC_AUDIT_DATA_INIT(&ad, FS);

	ad.u.fs.path.dentry = old_dentry;
	rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR,
@@ -1760,7 +1760,7 @@ static inline int may_rename(struct inode *old_dir,
static int superblock_has_perm(const struct cred *cred,
			       struct super_block *sb,
			       u32 perms,
			       struct common_audit_data *ad)
			       struct avc_audit_data *ad)
{
	struct superblock_security_struct *sbsec;
	u32 sid = cred_sid(cred);
@@ -2100,7 +2100,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
	const struct task_security_struct *old_tsec;
	struct task_security_struct *new_tsec;
	struct inode_security_struct *isec;
	struct common_audit_data ad;
	struct avc_audit_data ad;
	struct inode *inode = bprm->file->f_path.dentry->d_inode;
	int rc;

@@ -2138,7 +2138,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
			return rc;
	}

	COMMON_AUDIT_DATA_INIT(&ad, FS);
	AVC_AUDIT_DATA_INIT(&ad, FS);
	ad.u.fs.path = bprm->file->f_path;

	if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)
@@ -2231,7 +2231,7 @@ extern struct dentry *selinux_null;
static inline void flush_unauthorized_files(const struct cred *cred,
					    struct files_struct *files)
{
	struct common_audit_data ad;
	struct avc_audit_data ad;
	struct file *file, *devnull = NULL;
	struct tty_struct *tty;
	struct fdtable *fdt;
@@ -2265,7 +2265,7 @@ static inline void flush_unauthorized_files(const struct cred *cred,

	/* Revalidate access to inherited open files. */

	COMMON_AUDIT_DATA_INIT(&ad, FS);
	AVC_AUDIT_DATA_INIT(&ad, FS);

	spin_lock(&files->file_lock);
	for (;;) {
@@ -2514,7 +2514,7 @@ static int selinux_sb_copy_data(char *orig, char *copy)
static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
{
	const struct cred *cred = current_cred();
	struct common_audit_data ad;
	struct avc_audit_data ad;
	int rc;

	rc = superblock_doinit(sb, data);
@@ -2525,7 +2525,7 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
	if (flags & MS_KERNMOUNT)
		return 0;

	COMMON_AUDIT_DATA_INIT(&ad, FS);
	AVC_AUDIT_DATA_INIT(&ad, FS);
	ad.u.fs.path.dentry = sb->s_root;
	return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad);
}
@@ -2533,9 +2533,9 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
static int selinux_sb_statfs(struct dentry *dentry)
{
	const struct cred *cred = current_cred();
	struct common_audit_data ad;
	struct avc_audit_data ad;

	COMMON_AUDIT_DATA_INIT(&ad, FS);
	AVC_AUDIT_DATA_INIT(&ad, FS);
	ad.u.fs.path.dentry = dentry->d_sb->s_root;
	return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
}
@@ -2755,7 +2755,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
	struct inode *inode = dentry->d_inode;
	struct inode_security_struct *isec = inode->i_security;
	struct superblock_security_struct *sbsec;
	struct common_audit_data ad;
	struct avc_audit_data ad;
	u32 newsid, sid = current_sid();
	int rc = 0;

@@ -2769,7 +2769,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
	if (!is_owner_or_cap(inode))
		return -EPERM;

	COMMON_AUDIT_DATA_INIT(&ad, FS);
	AVC_AUDIT_DATA_INIT(&ad, FS);
	ad.u.fs.path.dentry = dentry;

	rc = avc_has_perm(sid, isec->sid, isec->sclass,
@@ -3401,7 +3401,7 @@ static void selinux_task_to_inode(struct task_struct *p,

/* Returns error only if unable to parse addresses */
static int selinux_parse_skb_ipv4(struct sk_buff *skb,
			struct common_audit_data *ad, u8 *proto)
			struct avc_audit_data *ad, u8 *proto)
{
	int offset, ihlen, ret = -EINVAL;
	struct iphdr _iph, *ih;
@@ -3482,7 +3482,7 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb,

/* Returns error only if unable to parse addresses */
static int selinux_parse_skb_ipv6(struct sk_buff *skb,
			struct common_audit_data *ad, u8 *proto)
			struct avc_audit_data *ad, u8 *proto)
{
	u8 nexthdr;
	int ret = -EINVAL, offset;
@@ -3553,7 +3553,7 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb,

#endif /* IPV6 */

static int selinux_parse_skb(struct sk_buff *skb, struct common_audit_data *ad,
static int selinux_parse_skb(struct sk_buff *skb, struct avc_audit_data *ad,
			     char **_addrp, int src, u8 *proto)
{
	char *addrp;
@@ -3635,7 +3635,7 @@ static int socket_has_perm(struct task_struct *task, struct socket *sock,
			   u32 perms)
{
	struct inode_security_struct *isec;
	struct common_audit_data ad;
	struct avc_audit_data ad;
	u32 sid;
	int err = 0;

@@ -3645,7 +3645,7 @@ static int socket_has_perm(struct task_struct *task, struct socket *sock,
		goto out;
	sid = task_sid(task);

	COMMON_AUDIT_DATA_INIT(&ad, NET);
	AVC_AUDIT_DATA_INIT(&ad, NET);
	ad.u.net.sk = sock->sk;
	err = avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad);

@@ -3732,7 +3732,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
	if (family == PF_INET || family == PF_INET6) {
		char *addrp;
		struct inode_security_struct *isec;
		struct common_audit_data ad;
		struct avc_audit_data ad;
		struct sockaddr_in *addr4 = NULL;
		struct sockaddr_in6 *addr6 = NULL;
		unsigned short snum;
@@ -3761,7 +3761,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
						      snum, &sid);
				if (err)
					goto out;
				COMMON_AUDIT_DATA_INIT(&ad, NET);
				AVC_AUDIT_DATA_INIT(&ad, NET);
				ad.u.net.sport = htons(snum);
				ad.u.net.family = family;
				err = avc_has_perm(isec->sid, sid,
@@ -3794,7 +3794,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
		if (err)
			goto out;

		COMMON_AUDIT_DATA_INIT(&ad, NET);
		AVC_AUDIT_DATA_INIT(&ad, NET);
		ad.u.net.sport = htons(snum);
		ad.u.net.family = family;

@@ -3828,7 +3828,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
	isec = SOCK_INODE(sock)->i_security;
	if (isec->sclass == SECCLASS_TCP_SOCKET ||
	    isec->sclass == SECCLASS_DCCP_SOCKET) {
		struct common_audit_data ad;
		struct avc_audit_data ad;
		struct sockaddr_in *addr4 = NULL;
		struct sockaddr_in6 *addr6 = NULL;
		unsigned short snum;
@@ -3853,7 +3853,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
		perm = (isec->sclass == SECCLASS_TCP_SOCKET) ?
		       TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT;

		COMMON_AUDIT_DATA_INIT(&ad, NET);
		AVC_AUDIT_DATA_INIT(&ad, NET);
		ad.u.net.dport = htons(snum);
		ad.u.net.family = sk->sk_family;
		err = avc_has_perm(isec->sid, sid, isec->sclass, perm, &ad);
@@ -3943,13 +3943,13 @@ static int selinux_socket_unix_stream_connect(struct socket *sock,
	struct sk_security_struct *ssec;
	struct inode_security_struct *isec;
	struct inode_security_struct *other_isec;
	struct common_audit_data ad;
	struct avc_audit_data ad;
	int err;

	isec = SOCK_INODE(sock)->i_security;
	other_isec = SOCK_INODE(other)->i_security;

	COMMON_AUDIT_DATA_INIT(&ad, NET);
	AVC_AUDIT_DATA_INIT(&ad, NET);
	ad.u.net.sk = other->sk;

	err = avc_has_perm(isec->sid, other_isec->sid,
@@ -3975,13 +3975,13 @@ static int selinux_socket_unix_may_send(struct socket *sock,
{
	struct inode_security_struct *isec;
	struct inode_security_struct *other_isec;
	struct common_audit_data ad;
	struct avc_audit_data ad;
	int err;

	isec = SOCK_INODE(sock)->i_security;
	other_isec = SOCK_INODE(other)->i_security;

	COMMON_AUDIT_DATA_INIT(&ad, NET);
	AVC_AUDIT_DATA_INIT(&ad, NET);
	ad.u.net.sk = other->sk;

	err = avc_has_perm(isec->sid, other_isec->sid,
@@ -3994,7 +3994,7 @@ static int selinux_socket_unix_may_send(struct socket *sock,

static int selinux_inet_sys_rcv_skb(int ifindex, char *addrp, u16 family,
				    u32 peer_sid,
				    struct common_audit_data *ad)
				    struct avc_audit_data *ad)
{
	int err;
	u32 if_sid;
@@ -4022,10 +4022,10 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
	struct sk_security_struct *sksec = sk->sk_security;
	u32 peer_sid;
	u32 sk_sid = sksec->sid;
	struct common_audit_data ad;
	struct avc_audit_data ad;
	char *addrp;

	COMMON_AUDIT_DATA_INIT(&ad, NET);
	AVC_AUDIT_DATA_INIT(&ad, NET);
	ad.u.net.netif = skb->iif;
	ad.u.net.family = family;
	err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
@@ -4063,7 +4063,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
	struct sk_security_struct *sksec = sk->sk_security;
	u16 family = sk->sk_family;
	u32 sk_sid = sksec->sid;
	struct common_audit_data ad;
	struct avc_audit_data ad;
	char *addrp;
	u8 secmark_active;
	u8 peerlbl_active;
@@ -4087,7 +4087,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
	if (!secmark_active && !peerlbl_active)
		return 0;

	COMMON_AUDIT_DATA_INIT(&ad, NET);
	AVC_AUDIT_DATA_INIT(&ad, NET);
	ad.u.net.netif = skb->iif;
	ad.u.net.family = family;
	err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
@@ -4345,7 +4345,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
	int err;
	char *addrp;
	u32 peer_sid;
	struct common_audit_data ad;
	struct avc_audit_data ad;
	u8 secmark_active;
	u8 netlbl_active;
	u8 peerlbl_active;
@@ -4362,7 +4362,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
	if (selinux_skb_peerlbl_sid(skb, family, &peer_sid) != 0)
		return NF_DROP;

	COMMON_AUDIT_DATA_INIT(&ad, NET);
	AVC_AUDIT_DATA_INIT(&ad, NET);
	ad.u.net.netif = ifindex;
	ad.u.net.family = family;
	if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0)
@@ -4450,7 +4450,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
{
	struct sock *sk = skb->sk;
	struct sk_security_struct *sksec;
	struct common_audit_data ad;
	struct avc_audit_data ad;
	char *addrp;
	u8 proto;

@@ -4458,7 +4458,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
		return NF_ACCEPT;
	sksec = sk->sk_security;

	COMMON_AUDIT_DATA_INIT(&ad, NET);
	AVC_AUDIT_DATA_INIT(&ad, NET);
	ad.u.net.netif = ifindex;
	ad.u.net.family = family;
	if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto))
@@ -4482,7 +4482,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
	u32 secmark_perm;
	u32 peer_sid;
	struct sock *sk;
	struct common_audit_data ad;
	struct avc_audit_data ad;
	char *addrp;
	u8 secmark_active;
	u8 peerlbl_active;
@@ -4541,7 +4541,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
		secmark_perm = PACKET__SEND;
	}

	COMMON_AUDIT_DATA_INIT(&ad, NET);
	AVC_AUDIT_DATA_INIT(&ad, NET);
	ad.u.net.netif = ifindex;
	ad.u.net.family = family;
	if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL))
@@ -4611,13 +4611,13 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
static int selinux_netlink_recv(struct sk_buff *skb, int capability)
{
	int err;
	struct common_audit_data ad;
	struct avc_audit_data ad;

	err = cap_netlink_recv(skb, capability);
	if (err)
		return err;

	COMMON_AUDIT_DATA_INIT(&ad, CAP);
	AVC_AUDIT_DATA_INIT(&ad, CAP);
	ad.u.cap = capability;

	return avc_has_perm(NETLINK_CB(skb).sid, NETLINK_CB(skb).sid,
@@ -4676,12 +4676,12 @@ static int ipc_has_perm(struct kern_ipc_perm *ipc_perms,
			u32 perms)
{
	struct ipc_security_struct *isec;
	struct common_audit_data ad;
	struct avc_audit_data ad;
	u32 sid = current_sid();

	isec = ipc_perms->security;

	COMMON_AUDIT_DATA_INIT(&ad, IPC);
	AVC_AUDIT_DATA_INIT(&ad, IPC);
	ad.u.ipc_id = ipc_perms->key;

	return avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad);
@@ -4701,7 +4701,7 @@ static void selinux_msg_msg_free_security(struct msg_msg *msg)
static int selinux_msg_queue_alloc_security(struct msg_queue *msq)
{
	struct ipc_security_struct *isec;
	struct common_audit_data ad;
	struct avc_audit_data ad;
	u32 sid = current_sid();
	int rc;

@@ -4711,7 +4711,7 @@ static int selinux_msg_queue_alloc_security(struct msg_queue *msq)

	isec = msq->q_perm.security;

	COMMON_AUDIT_DATA_INIT(&ad, IPC);
	AVC_AUDIT_DATA_INIT(&ad, IPC);
	ad.u.ipc_id = msq->q_perm.key;

	rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ,
@@ -4731,12 +4731,12 @@ static void selinux_msg_queue_free_security(struct msg_queue *msq)
static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg)
{
	struct ipc_security_struct *isec;
	struct common_audit_data ad;
	struct avc_audit_data ad;
	u32 sid = current_sid();

	isec = msq->q_perm.security;

	COMMON_AUDIT_DATA_INIT(&ad, IPC);
	AVC_AUDIT_DATA_INIT(&ad, IPC);
	ad.u.ipc_id = msq->q_perm.key;

	return avc_has_perm(sid, isec->sid, SECCLASS_MSGQ,
@@ -4775,7 +4775,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg,
{
	struct ipc_security_struct *isec;
	struct msg_security_struct *msec;
	struct common_audit_data ad;
	struct avc_audit_data ad;
	u32 sid = current_sid();
	int rc;

@@ -4796,7 +4796,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg,
			return rc;
	}

	COMMON_AUDIT_DATA_INIT(&ad, IPC);
	AVC_AUDIT_DATA_INIT(&ad, IPC);
	ad.u.ipc_id = msq->q_perm.key;

	/* Can this process write to the queue? */
@@ -4820,14 +4820,14 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
{
	struct ipc_security_struct *isec;
	struct msg_security_struct *msec;
	struct common_audit_data ad;
	struct avc_audit_data ad;
	u32 sid = task_sid(target);
	int rc;

	isec = msq->q_perm.security;
	msec = msg->security;

	COMMON_AUDIT_DATA_INIT(&ad, IPC);
	AVC_AUDIT_DATA_INIT(&ad, IPC);
	ad.u.ipc_id = msq->q_perm.key;

	rc = avc_has_perm(sid, isec->sid,
@@ -4842,7 +4842,7 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
static int selinux_shm_alloc_security(struct shmid_kernel *shp)
{
	struct ipc_security_struct *isec;
	struct common_audit_data ad;
	struct avc_audit_data ad;
	u32 sid = current_sid();
	int rc;

@@ -4852,7 +4852,7 @@ static int selinux_shm_alloc_security(struct shmid_kernel *shp)

	isec = shp->shm_perm.security;

	COMMON_AUDIT_DATA_INIT(&ad, IPC);
	AVC_AUDIT_DATA_INIT(&ad, IPC);
	ad.u.ipc_id = shp->shm_perm.key;

	rc = avc_has_perm(sid, isec->sid, SECCLASS_SHM,
@@ -4872,12 +4872,12 @@ static void selinux_shm_free_security(struct shmid_kernel *shp)
static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg)
{
	struct ipc_security_struct *isec;
	struct common_audit_data ad;
	struct avc_audit_data ad;
	u32 sid = current_sid();

	isec = shp->shm_perm.security;

	COMMON_AUDIT_DATA_INIT(&ad, IPC);
	AVC_AUDIT_DATA_INIT(&ad, IPC);
	ad.u.ipc_id = shp->shm_perm.key;

	return avc_has_perm(sid, isec->sid, SECCLASS_SHM,
@@ -4934,7 +4934,7 @@ static int selinux_shm_shmat(struct shmid_kernel *shp,
static int selinux_sem_alloc_security(struct sem_array *sma)
{
	struct ipc_security_struct *isec;
	struct common_audit_data ad;
	struct avc_audit_data ad;
	u32 sid = current_sid();
	int rc;

@@ -4944,7 +4944,7 @@ static int selinux_sem_alloc_security(struct sem_array *sma)

	isec = sma->sem_perm.security;

	COMMON_AUDIT_DATA_INIT(&ad, IPC);
	AVC_AUDIT_DATA_INIT(&ad, IPC);
	ad.u.ipc_id = sma->sem_perm.key;

	rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM,
@@ -4964,12 +4964,12 @@ static void selinux_sem_free_security(struct sem_array *sma)
static int selinux_sem_associate(struct sem_array *sma, int semflg)
{
	struct ipc_security_struct *isec;
	struct common_audit_data ad;
	struct avc_audit_data ad;
	u32 sid = current_sid();

	isec = sma->sem_perm.security;

	COMMON_AUDIT_DATA_INIT(&ad, IPC);
	AVC_AUDIT_DATA_INIT(&ad, IPC);
	ad.u.ipc_id = sma->sem_perm.key;

	return avc_has_perm(sid, isec->sid, SECCLASS_SEM,
+44 −5
Original line number Diff line number Diff line
@@ -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);

+2 −2
Original line number Diff line number Diff line
@@ -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;
}
Loading