162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * common LSM auditing functions
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Based on code written for SELinux by :
662306a36Sopenharmony_ci *			Stephen Smalley, <sds@tycho.nsa.gov>
762306a36Sopenharmony_ci * 			James Morris <jmorris@redhat.com>
862306a36Sopenharmony_ci * Author : Etienne Basset, <etienne.basset@ensta.org>
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <linux/types.h>
1262306a36Sopenharmony_ci#include <linux/stddef.h>
1362306a36Sopenharmony_ci#include <linux/kernel.h>
1462306a36Sopenharmony_ci#include <linux/gfp.h>
1562306a36Sopenharmony_ci#include <linux/fs.h>
1662306a36Sopenharmony_ci#include <linux/init.h>
1762306a36Sopenharmony_ci#include <net/sock.h>
1862306a36Sopenharmony_ci#include <linux/un.h>
1962306a36Sopenharmony_ci#include <net/af_unix.h>
2062306a36Sopenharmony_ci#include <linux/audit.h>
2162306a36Sopenharmony_ci#include <linux/ipv6.h>
2262306a36Sopenharmony_ci#include <linux/ip.h>
2362306a36Sopenharmony_ci#include <net/ip.h>
2462306a36Sopenharmony_ci#include <net/ipv6.h>
2562306a36Sopenharmony_ci#include <linux/tcp.h>
2662306a36Sopenharmony_ci#include <linux/udp.h>
2762306a36Sopenharmony_ci#include <linux/dccp.h>
2862306a36Sopenharmony_ci#include <linux/sctp.h>
2962306a36Sopenharmony_ci#include <linux/lsm_audit.h>
3062306a36Sopenharmony_ci#include <linux/security.h>
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci/**
3362306a36Sopenharmony_ci * ipv4_skb_to_auditdata : fill auditdata from skb
3462306a36Sopenharmony_ci * @skb : the skb
3562306a36Sopenharmony_ci * @ad : the audit data to fill
3662306a36Sopenharmony_ci * @proto : the layer 4 protocol
3762306a36Sopenharmony_ci *
3862306a36Sopenharmony_ci * return  0 on success
3962306a36Sopenharmony_ci */
4062306a36Sopenharmony_ciint ipv4_skb_to_auditdata(struct sk_buff *skb,
4162306a36Sopenharmony_ci		struct common_audit_data *ad, u8 *proto)
4262306a36Sopenharmony_ci{
4362306a36Sopenharmony_ci	int ret = 0;
4462306a36Sopenharmony_ci	struct iphdr *ih;
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci	ih = ip_hdr(skb);
4762306a36Sopenharmony_ci	ad->u.net->v4info.saddr = ih->saddr;
4862306a36Sopenharmony_ci	ad->u.net->v4info.daddr = ih->daddr;
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	if (proto)
5162306a36Sopenharmony_ci		*proto = ih->protocol;
5262306a36Sopenharmony_ci	/* non initial fragment */
5362306a36Sopenharmony_ci	if (ntohs(ih->frag_off) & IP_OFFSET)
5462306a36Sopenharmony_ci		return 0;
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci	switch (ih->protocol) {
5762306a36Sopenharmony_ci	case IPPROTO_TCP: {
5862306a36Sopenharmony_ci		struct tcphdr *th = tcp_hdr(skb);
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci		ad->u.net->sport = th->source;
6162306a36Sopenharmony_ci		ad->u.net->dport = th->dest;
6262306a36Sopenharmony_ci		break;
6362306a36Sopenharmony_ci	}
6462306a36Sopenharmony_ci	case IPPROTO_UDP: {
6562306a36Sopenharmony_ci		struct udphdr *uh = udp_hdr(skb);
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci		ad->u.net->sport = uh->source;
6862306a36Sopenharmony_ci		ad->u.net->dport = uh->dest;
6962306a36Sopenharmony_ci		break;
7062306a36Sopenharmony_ci	}
7162306a36Sopenharmony_ci	case IPPROTO_DCCP: {
7262306a36Sopenharmony_ci		struct dccp_hdr *dh = dccp_hdr(skb);
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci		ad->u.net->sport = dh->dccph_sport;
7562306a36Sopenharmony_ci		ad->u.net->dport = dh->dccph_dport;
7662306a36Sopenharmony_ci		break;
7762306a36Sopenharmony_ci	}
7862306a36Sopenharmony_ci	case IPPROTO_SCTP: {
7962306a36Sopenharmony_ci		struct sctphdr *sh = sctp_hdr(skb);
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci		ad->u.net->sport = sh->source;
8262306a36Sopenharmony_ci		ad->u.net->dport = sh->dest;
8362306a36Sopenharmony_ci		break;
8462306a36Sopenharmony_ci	}
8562306a36Sopenharmony_ci	default:
8662306a36Sopenharmony_ci		ret = -EINVAL;
8762306a36Sopenharmony_ci	}
8862306a36Sopenharmony_ci	return ret;
8962306a36Sopenharmony_ci}
9062306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6)
9162306a36Sopenharmony_ci/**
9262306a36Sopenharmony_ci * ipv6_skb_to_auditdata : fill auditdata from skb
9362306a36Sopenharmony_ci * @skb : the skb
9462306a36Sopenharmony_ci * @ad : the audit data to fill
9562306a36Sopenharmony_ci * @proto : the layer 4 protocol
9662306a36Sopenharmony_ci *
9762306a36Sopenharmony_ci * return  0 on success
9862306a36Sopenharmony_ci */
9962306a36Sopenharmony_ciint ipv6_skb_to_auditdata(struct sk_buff *skb,
10062306a36Sopenharmony_ci		struct common_audit_data *ad, u8 *proto)
10162306a36Sopenharmony_ci{
10262306a36Sopenharmony_ci	int offset, ret = 0;
10362306a36Sopenharmony_ci	struct ipv6hdr *ip6;
10462306a36Sopenharmony_ci	u8 nexthdr;
10562306a36Sopenharmony_ci	__be16 frag_off;
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci	ip6 = ipv6_hdr(skb);
10862306a36Sopenharmony_ci	ad->u.net->v6info.saddr = ip6->saddr;
10962306a36Sopenharmony_ci	ad->u.net->v6info.daddr = ip6->daddr;
11062306a36Sopenharmony_ci	/* IPv6 can have several extension header before the Transport header
11162306a36Sopenharmony_ci	 * skip them */
11262306a36Sopenharmony_ci	offset = skb_network_offset(skb);
11362306a36Sopenharmony_ci	offset += sizeof(*ip6);
11462306a36Sopenharmony_ci	nexthdr = ip6->nexthdr;
11562306a36Sopenharmony_ci	offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off);
11662306a36Sopenharmony_ci	if (offset < 0)
11762306a36Sopenharmony_ci		return 0;
11862306a36Sopenharmony_ci	if (proto)
11962306a36Sopenharmony_ci		*proto = nexthdr;
12062306a36Sopenharmony_ci	switch (nexthdr) {
12162306a36Sopenharmony_ci	case IPPROTO_TCP: {
12262306a36Sopenharmony_ci		struct tcphdr _tcph, *th;
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci		th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
12562306a36Sopenharmony_ci		if (th == NULL)
12662306a36Sopenharmony_ci			break;
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci		ad->u.net->sport = th->source;
12962306a36Sopenharmony_ci		ad->u.net->dport = th->dest;
13062306a36Sopenharmony_ci		break;
13162306a36Sopenharmony_ci	}
13262306a36Sopenharmony_ci	case IPPROTO_UDP: {
13362306a36Sopenharmony_ci		struct udphdr _udph, *uh;
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci		uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
13662306a36Sopenharmony_ci		if (uh == NULL)
13762306a36Sopenharmony_ci			break;
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci		ad->u.net->sport = uh->source;
14062306a36Sopenharmony_ci		ad->u.net->dport = uh->dest;
14162306a36Sopenharmony_ci		break;
14262306a36Sopenharmony_ci	}
14362306a36Sopenharmony_ci	case IPPROTO_DCCP: {
14462306a36Sopenharmony_ci		struct dccp_hdr _dccph, *dh;
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci		dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
14762306a36Sopenharmony_ci		if (dh == NULL)
14862306a36Sopenharmony_ci			break;
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci		ad->u.net->sport = dh->dccph_sport;
15162306a36Sopenharmony_ci		ad->u.net->dport = dh->dccph_dport;
15262306a36Sopenharmony_ci		break;
15362306a36Sopenharmony_ci	}
15462306a36Sopenharmony_ci	case IPPROTO_SCTP: {
15562306a36Sopenharmony_ci		struct sctphdr _sctph, *sh;
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci		sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph);
15862306a36Sopenharmony_ci		if (sh == NULL)
15962306a36Sopenharmony_ci			break;
16062306a36Sopenharmony_ci		ad->u.net->sport = sh->source;
16162306a36Sopenharmony_ci		ad->u.net->dport = sh->dest;
16262306a36Sopenharmony_ci		break;
16362306a36Sopenharmony_ci	}
16462306a36Sopenharmony_ci	default:
16562306a36Sopenharmony_ci		ret = -EINVAL;
16662306a36Sopenharmony_ci	}
16762306a36Sopenharmony_ci	return ret;
16862306a36Sopenharmony_ci}
16962306a36Sopenharmony_ci#endif
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_cistatic inline void print_ipv6_addr(struct audit_buffer *ab,
17362306a36Sopenharmony_ci				   const struct in6_addr *addr, __be16 port,
17462306a36Sopenharmony_ci				   char *name1, char *name2)
17562306a36Sopenharmony_ci{
17662306a36Sopenharmony_ci	if (!ipv6_addr_any(addr))
17762306a36Sopenharmony_ci		audit_log_format(ab, " %s=%pI6c", name1, addr);
17862306a36Sopenharmony_ci	if (port)
17962306a36Sopenharmony_ci		audit_log_format(ab, " %s=%d", name2, ntohs(port));
18062306a36Sopenharmony_ci}
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_cistatic inline void print_ipv4_addr(struct audit_buffer *ab, __be32 addr,
18362306a36Sopenharmony_ci				   __be16 port, char *name1, char *name2)
18462306a36Sopenharmony_ci{
18562306a36Sopenharmony_ci	if (addr)
18662306a36Sopenharmony_ci		audit_log_format(ab, " %s=%pI4", name1, &addr);
18762306a36Sopenharmony_ci	if (port)
18862306a36Sopenharmony_ci		audit_log_format(ab, " %s=%d", name2, ntohs(port));
18962306a36Sopenharmony_ci}
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci/**
19262306a36Sopenharmony_ci * dump_common_audit_data - helper to dump common audit data
19362306a36Sopenharmony_ci * @ab : the audit buffer
19462306a36Sopenharmony_ci * @a : common audit data
19562306a36Sopenharmony_ci *
19662306a36Sopenharmony_ci */
19762306a36Sopenharmony_cistatic void dump_common_audit_data(struct audit_buffer *ab,
19862306a36Sopenharmony_ci				   struct common_audit_data *a)
19962306a36Sopenharmony_ci{
20062306a36Sopenharmony_ci	char comm[sizeof(current->comm)];
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci	/*
20362306a36Sopenharmony_ci	 * To keep stack sizes in check force programmers to notice if they
20462306a36Sopenharmony_ci	 * start making this union too large!  See struct lsm_network_audit
20562306a36Sopenharmony_ci	 * as an example of how to deal with large data.
20662306a36Sopenharmony_ci	 */
20762306a36Sopenharmony_ci	BUILD_BUG_ON(sizeof(a->u) > sizeof(void *)*2);
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci	audit_log_format(ab, " pid=%d comm=", task_tgid_nr(current));
21062306a36Sopenharmony_ci	audit_log_untrustedstring(ab, memcpy(comm, current->comm, sizeof(comm)));
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci	switch (a->type) {
21362306a36Sopenharmony_ci	case LSM_AUDIT_DATA_NONE:
21462306a36Sopenharmony_ci		return;
21562306a36Sopenharmony_ci	case LSM_AUDIT_DATA_IPC:
21662306a36Sopenharmony_ci		audit_log_format(ab, " ipc_key=%d ", a->u.ipc_id);
21762306a36Sopenharmony_ci		break;
21862306a36Sopenharmony_ci	case LSM_AUDIT_DATA_CAP:
21962306a36Sopenharmony_ci		audit_log_format(ab, " capability=%d ", a->u.cap);
22062306a36Sopenharmony_ci		break;
22162306a36Sopenharmony_ci	case LSM_AUDIT_DATA_PATH: {
22262306a36Sopenharmony_ci		struct inode *inode;
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci		audit_log_d_path(ab, " path=", &a->u.path);
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci		inode = d_backing_inode(a->u.path.dentry);
22762306a36Sopenharmony_ci		if (inode) {
22862306a36Sopenharmony_ci			audit_log_format(ab, " dev=");
22962306a36Sopenharmony_ci			audit_log_untrustedstring(ab, inode->i_sb->s_id);
23062306a36Sopenharmony_ci			audit_log_format(ab, " ino=%lu", inode->i_ino);
23162306a36Sopenharmony_ci		}
23262306a36Sopenharmony_ci		break;
23362306a36Sopenharmony_ci	}
23462306a36Sopenharmony_ci	case LSM_AUDIT_DATA_FILE: {
23562306a36Sopenharmony_ci		struct inode *inode;
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci		audit_log_d_path(ab, " path=", &a->u.file->f_path);
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ci		inode = file_inode(a->u.file);
24062306a36Sopenharmony_ci		if (inode) {
24162306a36Sopenharmony_ci			audit_log_format(ab, " dev=");
24262306a36Sopenharmony_ci			audit_log_untrustedstring(ab, inode->i_sb->s_id);
24362306a36Sopenharmony_ci			audit_log_format(ab, " ino=%lu", inode->i_ino);
24462306a36Sopenharmony_ci		}
24562306a36Sopenharmony_ci		break;
24662306a36Sopenharmony_ci	}
24762306a36Sopenharmony_ci	case LSM_AUDIT_DATA_IOCTL_OP: {
24862306a36Sopenharmony_ci		struct inode *inode;
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_ci		audit_log_d_path(ab, " path=", &a->u.op->path);
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_ci		inode = a->u.op->path.dentry->d_inode;
25362306a36Sopenharmony_ci		if (inode) {
25462306a36Sopenharmony_ci			audit_log_format(ab, " dev=");
25562306a36Sopenharmony_ci			audit_log_untrustedstring(ab, inode->i_sb->s_id);
25662306a36Sopenharmony_ci			audit_log_format(ab, " ino=%lu", inode->i_ino);
25762306a36Sopenharmony_ci		}
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci		audit_log_format(ab, " ioctlcmd=0x%hx", a->u.op->cmd);
26062306a36Sopenharmony_ci		break;
26162306a36Sopenharmony_ci	}
26262306a36Sopenharmony_ci	case LSM_AUDIT_DATA_DENTRY: {
26362306a36Sopenharmony_ci		struct inode *inode;
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci		audit_log_format(ab, " name=");
26662306a36Sopenharmony_ci		spin_lock(&a->u.dentry->d_lock);
26762306a36Sopenharmony_ci		audit_log_untrustedstring(ab, a->u.dentry->d_name.name);
26862306a36Sopenharmony_ci		spin_unlock(&a->u.dentry->d_lock);
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci		inode = d_backing_inode(a->u.dentry);
27162306a36Sopenharmony_ci		if (inode) {
27262306a36Sopenharmony_ci			audit_log_format(ab, " dev=");
27362306a36Sopenharmony_ci			audit_log_untrustedstring(ab, inode->i_sb->s_id);
27462306a36Sopenharmony_ci			audit_log_format(ab, " ino=%lu", inode->i_ino);
27562306a36Sopenharmony_ci		}
27662306a36Sopenharmony_ci		break;
27762306a36Sopenharmony_ci	}
27862306a36Sopenharmony_ci	case LSM_AUDIT_DATA_INODE: {
27962306a36Sopenharmony_ci		struct dentry *dentry;
28062306a36Sopenharmony_ci		struct inode *inode;
28162306a36Sopenharmony_ci
28262306a36Sopenharmony_ci		rcu_read_lock();
28362306a36Sopenharmony_ci		inode = a->u.inode;
28462306a36Sopenharmony_ci		dentry = d_find_alias_rcu(inode);
28562306a36Sopenharmony_ci		if (dentry) {
28662306a36Sopenharmony_ci			audit_log_format(ab, " name=");
28762306a36Sopenharmony_ci			spin_lock(&dentry->d_lock);
28862306a36Sopenharmony_ci			audit_log_untrustedstring(ab, dentry->d_name.name);
28962306a36Sopenharmony_ci			spin_unlock(&dentry->d_lock);
29062306a36Sopenharmony_ci		}
29162306a36Sopenharmony_ci		audit_log_format(ab, " dev=");
29262306a36Sopenharmony_ci		audit_log_untrustedstring(ab, inode->i_sb->s_id);
29362306a36Sopenharmony_ci		audit_log_format(ab, " ino=%lu", inode->i_ino);
29462306a36Sopenharmony_ci		rcu_read_unlock();
29562306a36Sopenharmony_ci		break;
29662306a36Sopenharmony_ci	}
29762306a36Sopenharmony_ci	case LSM_AUDIT_DATA_TASK: {
29862306a36Sopenharmony_ci		struct task_struct *tsk = a->u.tsk;
29962306a36Sopenharmony_ci		if (tsk) {
30062306a36Sopenharmony_ci			pid_t pid = task_tgid_nr(tsk);
30162306a36Sopenharmony_ci			if (pid) {
30262306a36Sopenharmony_ci				char comm[sizeof(tsk->comm)];
30362306a36Sopenharmony_ci				audit_log_format(ab, " opid=%d ocomm=", pid);
30462306a36Sopenharmony_ci				audit_log_untrustedstring(ab,
30562306a36Sopenharmony_ci				    memcpy(comm, tsk->comm, sizeof(comm)));
30662306a36Sopenharmony_ci			}
30762306a36Sopenharmony_ci		}
30862306a36Sopenharmony_ci		break;
30962306a36Sopenharmony_ci	}
31062306a36Sopenharmony_ci	case LSM_AUDIT_DATA_NET:
31162306a36Sopenharmony_ci		if (a->u.net->sk) {
31262306a36Sopenharmony_ci			const struct sock *sk = a->u.net->sk;
31362306a36Sopenharmony_ci			const struct unix_sock *u;
31462306a36Sopenharmony_ci			struct unix_address *addr;
31562306a36Sopenharmony_ci			int len = 0;
31662306a36Sopenharmony_ci			char *p = NULL;
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ci			switch (sk->sk_family) {
31962306a36Sopenharmony_ci			case AF_INET: {
32062306a36Sopenharmony_ci				const struct inet_sock *inet = inet_sk(sk);
32162306a36Sopenharmony_ci
32262306a36Sopenharmony_ci				print_ipv4_addr(ab, inet->inet_rcv_saddr,
32362306a36Sopenharmony_ci						inet->inet_sport,
32462306a36Sopenharmony_ci						"laddr", "lport");
32562306a36Sopenharmony_ci				print_ipv4_addr(ab, inet->inet_daddr,
32662306a36Sopenharmony_ci						inet->inet_dport,
32762306a36Sopenharmony_ci						"faddr", "fport");
32862306a36Sopenharmony_ci				break;
32962306a36Sopenharmony_ci			}
33062306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6)
33162306a36Sopenharmony_ci			case AF_INET6: {
33262306a36Sopenharmony_ci				const struct inet_sock *inet = inet_sk(sk);
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci				print_ipv6_addr(ab, &sk->sk_v6_rcv_saddr,
33562306a36Sopenharmony_ci						inet->inet_sport,
33662306a36Sopenharmony_ci						"laddr", "lport");
33762306a36Sopenharmony_ci				print_ipv6_addr(ab, &sk->sk_v6_daddr,
33862306a36Sopenharmony_ci						inet->inet_dport,
33962306a36Sopenharmony_ci						"faddr", "fport");
34062306a36Sopenharmony_ci				break;
34162306a36Sopenharmony_ci			}
34262306a36Sopenharmony_ci#endif
34362306a36Sopenharmony_ci			case AF_UNIX:
34462306a36Sopenharmony_ci				u = unix_sk(sk);
34562306a36Sopenharmony_ci				addr = smp_load_acquire(&u->addr);
34662306a36Sopenharmony_ci				if (!addr)
34762306a36Sopenharmony_ci					break;
34862306a36Sopenharmony_ci				if (u->path.dentry) {
34962306a36Sopenharmony_ci					audit_log_d_path(ab, " path=", &u->path);
35062306a36Sopenharmony_ci					break;
35162306a36Sopenharmony_ci				}
35262306a36Sopenharmony_ci				len = addr->len-sizeof(short);
35362306a36Sopenharmony_ci				p = &addr->name->sun_path[0];
35462306a36Sopenharmony_ci				audit_log_format(ab, " path=");
35562306a36Sopenharmony_ci				if (*p)
35662306a36Sopenharmony_ci					audit_log_untrustedstring(ab, p);
35762306a36Sopenharmony_ci				else
35862306a36Sopenharmony_ci					audit_log_n_hex(ab, p, len);
35962306a36Sopenharmony_ci				break;
36062306a36Sopenharmony_ci			}
36162306a36Sopenharmony_ci		}
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci		switch (a->u.net->family) {
36462306a36Sopenharmony_ci		case AF_INET:
36562306a36Sopenharmony_ci			print_ipv4_addr(ab, a->u.net->v4info.saddr,
36662306a36Sopenharmony_ci					a->u.net->sport,
36762306a36Sopenharmony_ci					"saddr", "src");
36862306a36Sopenharmony_ci			print_ipv4_addr(ab, a->u.net->v4info.daddr,
36962306a36Sopenharmony_ci					a->u.net->dport,
37062306a36Sopenharmony_ci					"daddr", "dest");
37162306a36Sopenharmony_ci			break;
37262306a36Sopenharmony_ci		case AF_INET6:
37362306a36Sopenharmony_ci			print_ipv6_addr(ab, &a->u.net->v6info.saddr,
37462306a36Sopenharmony_ci					a->u.net->sport,
37562306a36Sopenharmony_ci					"saddr", "src");
37662306a36Sopenharmony_ci			print_ipv6_addr(ab, &a->u.net->v6info.daddr,
37762306a36Sopenharmony_ci					a->u.net->dport,
37862306a36Sopenharmony_ci					"daddr", "dest");
37962306a36Sopenharmony_ci			break;
38062306a36Sopenharmony_ci		}
38162306a36Sopenharmony_ci		if (a->u.net->netif > 0) {
38262306a36Sopenharmony_ci			struct net_device *dev;
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_ci			/* NOTE: we always use init's namespace */
38562306a36Sopenharmony_ci			dev = dev_get_by_index(&init_net, a->u.net->netif);
38662306a36Sopenharmony_ci			if (dev) {
38762306a36Sopenharmony_ci				audit_log_format(ab, " netif=%s", dev->name);
38862306a36Sopenharmony_ci				dev_put(dev);
38962306a36Sopenharmony_ci			}
39062306a36Sopenharmony_ci		}
39162306a36Sopenharmony_ci		break;
39262306a36Sopenharmony_ci#ifdef CONFIG_KEYS
39362306a36Sopenharmony_ci	case LSM_AUDIT_DATA_KEY:
39462306a36Sopenharmony_ci		audit_log_format(ab, " key_serial=%u", a->u.key_struct.key);
39562306a36Sopenharmony_ci		if (a->u.key_struct.key_desc) {
39662306a36Sopenharmony_ci			audit_log_format(ab, " key_desc=");
39762306a36Sopenharmony_ci			audit_log_untrustedstring(ab, a->u.key_struct.key_desc);
39862306a36Sopenharmony_ci		}
39962306a36Sopenharmony_ci		break;
40062306a36Sopenharmony_ci#endif
40162306a36Sopenharmony_ci	case LSM_AUDIT_DATA_KMOD:
40262306a36Sopenharmony_ci		audit_log_format(ab, " kmod=");
40362306a36Sopenharmony_ci		audit_log_untrustedstring(ab, a->u.kmod_name);
40462306a36Sopenharmony_ci		break;
40562306a36Sopenharmony_ci	case LSM_AUDIT_DATA_IBPKEY: {
40662306a36Sopenharmony_ci		struct in6_addr sbn_pfx;
40762306a36Sopenharmony_ci
40862306a36Sopenharmony_ci		memset(&sbn_pfx.s6_addr, 0,
40962306a36Sopenharmony_ci		       sizeof(sbn_pfx.s6_addr));
41062306a36Sopenharmony_ci		memcpy(&sbn_pfx.s6_addr, &a->u.ibpkey->subnet_prefix,
41162306a36Sopenharmony_ci		       sizeof(a->u.ibpkey->subnet_prefix));
41262306a36Sopenharmony_ci		audit_log_format(ab, " pkey=0x%x subnet_prefix=%pI6c",
41362306a36Sopenharmony_ci				 a->u.ibpkey->pkey, &sbn_pfx);
41462306a36Sopenharmony_ci		break;
41562306a36Sopenharmony_ci	}
41662306a36Sopenharmony_ci	case LSM_AUDIT_DATA_IBENDPORT:
41762306a36Sopenharmony_ci		audit_log_format(ab, " device=%s port_num=%u",
41862306a36Sopenharmony_ci				 a->u.ibendport->dev_name,
41962306a36Sopenharmony_ci				 a->u.ibendport->port);
42062306a36Sopenharmony_ci		break;
42162306a36Sopenharmony_ci	case LSM_AUDIT_DATA_LOCKDOWN:
42262306a36Sopenharmony_ci		audit_log_format(ab, " lockdown_reason=\"%s\"",
42362306a36Sopenharmony_ci				 lockdown_reasons[a->u.reason]);
42462306a36Sopenharmony_ci		break;
42562306a36Sopenharmony_ci	case LSM_AUDIT_DATA_ANONINODE:
42662306a36Sopenharmony_ci		audit_log_format(ab, " anonclass=%s", a->u.anonclass);
42762306a36Sopenharmony_ci		break;
42862306a36Sopenharmony_ci	} /* switch (a->type) */
42962306a36Sopenharmony_ci}
43062306a36Sopenharmony_ci
43162306a36Sopenharmony_ci/**
43262306a36Sopenharmony_ci * common_lsm_audit - generic LSM auditing function
43362306a36Sopenharmony_ci * @a:  auxiliary audit data
43462306a36Sopenharmony_ci * @pre_audit: lsm-specific pre-audit callback
43562306a36Sopenharmony_ci * @post_audit: lsm-specific post-audit callback
43662306a36Sopenharmony_ci *
43762306a36Sopenharmony_ci * setup the audit buffer for common security information
43862306a36Sopenharmony_ci * uses callback to print LSM specific information
43962306a36Sopenharmony_ci */
44062306a36Sopenharmony_civoid common_lsm_audit(struct common_audit_data *a,
44162306a36Sopenharmony_ci	void (*pre_audit)(struct audit_buffer *, void *),
44262306a36Sopenharmony_ci	void (*post_audit)(struct audit_buffer *, void *))
44362306a36Sopenharmony_ci{
44462306a36Sopenharmony_ci	struct audit_buffer *ab;
44562306a36Sopenharmony_ci
44662306a36Sopenharmony_ci	if (a == NULL)
44762306a36Sopenharmony_ci		return;
44862306a36Sopenharmony_ci	/* we use GFP_ATOMIC so we won't sleep */
44962306a36Sopenharmony_ci	ab = audit_log_start(audit_context(), GFP_ATOMIC | __GFP_NOWARN,
45062306a36Sopenharmony_ci			     AUDIT_AVC);
45162306a36Sopenharmony_ci
45262306a36Sopenharmony_ci	if (ab == NULL)
45362306a36Sopenharmony_ci		return;
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_ci	if (pre_audit)
45662306a36Sopenharmony_ci		pre_audit(ab, a);
45762306a36Sopenharmony_ci
45862306a36Sopenharmony_ci	dump_common_audit_data(ab, a);
45962306a36Sopenharmony_ci
46062306a36Sopenharmony_ci	if (post_audit)
46162306a36Sopenharmony_ci		post_audit(ab, a);
46262306a36Sopenharmony_ci
46362306a36Sopenharmony_ci	audit_log_end(ab);
46462306a36Sopenharmony_ci}
465