File Index
Files and directories
Sign in
FILE

lsm_audit.c

File preview with syntax highlighting.

linux-6.19.14/security/lsm_audit.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * common LSM auditing functions
  4 *
  5 * Based on code written for SELinux by :
  6 *			Stephen Smalley
  7 * 			James Morris <jmorris@redhat.com>
  8 * Author : Etienne Basset, <etienne.basset@ensta.org>
  9 */
 10
 11#include <linux/types.h>
 12#include <linux/stddef.h>
 13#include <linux/kernel.h>
 14#include <linux/gfp.h>
 15#include <linux/fs.h>
 16#include <linux/init.h>
 17#include <net/sock.h>
 18#include <linux/un.h>
 19#include <net/af_unix.h>
 20#include <linux/audit.h>
 21#include <linux/ipv6.h>
 22#include <linux/ip.h>
 23#include <net/ip.h>
 24#include <net/ipv6.h>
 25#include <linux/tcp.h>
 26#include <linux/udp.h>
 27#include <linux/sctp.h>
 28#include <linux/lsm_audit.h>
 29#include <linux/security.h>
 30
 31/**
 32 * ipv4_skb_to_auditdata : fill auditdata from skb
 33 * @skb : the skb
 34 * @ad : the audit data to fill
 35 * @proto : the layer 4 protocol
 36 *
 37 * return  0 on success
 38 */
 39int ipv4_skb_to_auditdata(struct sk_buff *skb,
 40		struct common_audit_data *ad, u8 *proto)
 41{
 42	int ret = 0;
 43	struct iphdr *ih;
 44
 45	ih = ip_hdr(skb);
 46	ad->u.net->v4info.saddr = ih->saddr;
 47	ad->u.net->v4info.daddr = ih->daddr;
 48
 49	if (proto)
 50		*proto = ih->protocol;
 51	/* non initial fragment */
 52	if (ntohs(ih->frag_off) & IP_OFFSET)
 53		return 0;
 54
 55	switch (ih->protocol) {
 56	case IPPROTO_TCP: {
 57		struct tcphdr *th = tcp_hdr(skb);
 58
 59		ad->u.net->sport = th->source;
 60		ad->u.net->dport = th->dest;
 61		break;
 62	}
 63	case IPPROTO_UDP: {
 64		struct udphdr *uh = udp_hdr(skb);
 65
 66		ad->u.net->sport = uh->source;
 67		ad->u.net->dport = uh->dest;
 68		break;
 69	}
 70	case IPPROTO_SCTP: {
 71		struct sctphdr *sh = sctp_hdr(skb);
 72
 73		ad->u.net->sport = sh->source;
 74		ad->u.net->dport = sh->dest;
 75		break;
 76	}
 77	default:
 78		ret = -EINVAL;
 79	}
 80	return ret;
 81}
 82#if IS_ENABLED(CONFIG_IPV6)
 83/**
 84 * ipv6_skb_to_auditdata : fill auditdata from skb
 85 * @skb : the skb
 86 * @ad : the audit data to fill
 87 * @proto : the layer 4 protocol
 88 *
 89 * return  0 on success
 90 */
 91int ipv6_skb_to_auditdata(struct sk_buff *skb,
 92		struct common_audit_data *ad, u8 *proto)
 93{
 94	int offset, ret = 0;
 95	struct ipv6hdr *ip6;
 96	u8 nexthdr;
 97	__be16 frag_off;
 98
 99	ip6 = ipv6_hdr(skb);
100	ad->u.net->v6info.saddr = ip6->saddr;
101	ad->u.net->v6info.daddr = ip6->daddr;
102	/* IPv6 can have several extension header before the Transport header
103	 * skip them */
104	offset = skb_network_offset(skb);
105	offset += sizeof(*ip6);
106	nexthdr = ip6->nexthdr;
107	offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off);
108	if (offset < 0)
109		return 0;
110	if (proto)
111		*proto = nexthdr;
112	switch (nexthdr) {
113	case IPPROTO_TCP: {
114		struct tcphdr _tcph, *th;
115
116		th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
117		if (th == NULL)
118			break;
119
120		ad->u.net->sport = th->source;
121		ad->u.net->dport = th->dest;
122		break;
123	}
124	case IPPROTO_UDP: {
125		struct udphdr _udph, *uh;
126
127		uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
128		if (uh == NULL)
129			break;
130
131		ad->u.net->sport = uh->source;
132		ad->u.net->dport = uh->dest;
133		break;
134	}
135	case IPPROTO_SCTP: {
136		struct sctphdr _sctph, *sh;
137
138		sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph);
139		if (sh == NULL)
140			break;
141		ad->u.net->sport = sh->source;
142		ad->u.net->dport = sh->dest;
143		break;
144	}
145	default:
146		ret = -EINVAL;
147	}
148	return ret;
149}
150#endif
151
152
153static inline void print_ipv6_addr(struct audit_buffer *ab,
154				   const struct in6_addr *addr, __be16 port,
155				   const char *name1, const char *name2)
156{
157	if (!ipv6_addr_any(addr))
158		audit_log_format(ab, " %s=%pI6c", name1, addr);
159	if (port)
160		audit_log_format(ab, " %s=%d", name2, ntohs(port));
161}
162
163static inline void print_ipv4_addr(struct audit_buffer *ab, __be32 addr,
164				   __be16 port, const char *name1, const char *name2)
165{
166	if (addr)
167		audit_log_format(ab, " %s=%pI4", name1, &addr);
168	if (port)
169		audit_log_format(ab, " %s=%d", name2, ntohs(port));
170}
171
172/**
173 * audit_log_lsm_data - helper to log common LSM audit data
174 * @ab : the audit buffer
175 * @a : common audit data
176 */
177void audit_log_lsm_data(struct audit_buffer *ab,
178			const struct common_audit_data *a)
179{
180	/*
181	 * To keep stack sizes in check force programmers to notice if they
182	 * start making this union too large!  See struct lsm_network_audit
183	 * as an example of how to deal with large data.
184	 */
185	BUILD_BUG_ON(sizeof(a->u) > sizeof(void *)*2);
186
187	switch (a->type) {
188	case LSM_AUDIT_DATA_NONE:
189		return;
190	case LSM_AUDIT_DATA_IPC:
191		audit_log_format(ab, " ipc_key=%d ", a->u.ipc_id);
192		break;
193	case LSM_AUDIT_DATA_CAP:
194		audit_log_format(ab, " capability=%d ", a->u.cap);
195		break;
196	case LSM_AUDIT_DATA_PATH: {
197		struct inode *inode;
198
199		audit_log_d_path(ab, " path=", &a->u.path);
200
201		inode = d_backing_inode(a->u.path.dentry);
202		if (inode) {
203			audit_log_format(ab, " dev=");
204			audit_log_untrustedstring(ab, inode->i_sb->s_id);
205			audit_log_format(ab, " ino=%lu", inode->i_ino);
206		}
207		break;
208	}
209	case LSM_AUDIT_DATA_FILE: {
210		struct inode *inode;
211
212		audit_log_d_path(ab, " path=", &a->u.file->f_path);
213
214		inode = file_inode(a->u.file);
215		if (inode) {
216			audit_log_format(ab, " dev=");
217			audit_log_untrustedstring(ab, inode->i_sb->s_id);
218			audit_log_format(ab, " ino=%lu", inode->i_ino);
219		}
220		break;
221	}
222	case LSM_AUDIT_DATA_IOCTL_OP: {
223		struct inode *inode;
224
225		audit_log_d_path(ab, " path=", &a->u.op->path);
226
227		inode = a->u.op->path.dentry->d_inode;
228		if (inode) {
229			audit_log_format(ab, " dev=");
230			audit_log_untrustedstring(ab, inode->i_sb->s_id);
231			audit_log_format(ab, " ino=%lu", inode->i_ino);
232		}
233
234		audit_log_format(ab, " ioctlcmd=0x%hx", a->u.op->cmd);
235		break;
236	}
237	case LSM_AUDIT_DATA_DENTRY: {
238		struct inode *inode;
239
240		audit_log_format(ab, " name=");
241		spin_lock(&a->u.dentry->d_lock);
242		audit_log_untrustedstring(ab, a->u.dentry->d_name.name);
243		spin_unlock(&a->u.dentry->d_lock);
244
245		inode = d_backing_inode(a->u.dentry);
246		if (inode) {
247			audit_log_format(ab, " dev=");
248			audit_log_untrustedstring(ab, inode->i_sb->s_id);
249			audit_log_format(ab, " ino=%lu", inode->i_ino);
250		}
251		break;
252	}
253	case LSM_AUDIT_DATA_INODE: {
254		struct dentry *dentry;
255		struct inode *inode;
256
257		rcu_read_lock();
258		inode = a->u.inode;
259		dentry = d_find_alias_rcu(inode);
260		if (dentry) {
261			audit_log_format(ab, " name=");
262			spin_lock(&dentry->d_lock);
263			audit_log_untrustedstring(ab, dentry->d_name.name);
264			spin_unlock(&dentry->d_lock);
265		}
266		audit_log_format(ab, " dev=");
267		audit_log_untrustedstring(ab, inode->i_sb->s_id);
268		audit_log_format(ab, " ino=%lu", inode->i_ino);
269		rcu_read_unlock();
270		break;
271	}
272	case LSM_AUDIT_DATA_TASK: {
273		struct task_struct *tsk = a->u.tsk;
274		if (tsk) {
275			pid_t pid = task_tgid_nr(tsk);
276			if (pid) {
277				char tskcomm[sizeof(tsk->comm)];
278				audit_log_format(ab, " opid=%d ocomm=", pid);
279				audit_log_untrustedstring(ab,
280				    get_task_comm(tskcomm, tsk));
281			}
282		}
283		break;
284	}
285	case LSM_AUDIT_DATA_NET:
286		if (a->u.net->sk) {
287			const struct sock *sk = a->u.net->sk;
288			const struct unix_sock *u;
289			struct unix_address *addr;
290			int len = 0;
291			char *p = NULL;
292
293			switch (sk->sk_family) {
294			case AF_INET: {
295				const struct inet_sock *inet = inet_sk(sk);
296
297				print_ipv4_addr(ab, inet->inet_rcv_saddr,
298						inet->inet_sport,
299						"laddr", "lport");
300				print_ipv4_addr(ab, inet->inet_daddr,
301						inet->inet_dport,
302						"faddr", "fport");
303				break;
304			}
305#if IS_ENABLED(CONFIG_IPV6)
306			case AF_INET6: {
307				const struct inet_sock *inet = inet_sk(sk);
308
309				print_ipv6_addr(ab, &sk->sk_v6_rcv_saddr,
310						inet->inet_sport,
311						"laddr", "lport");
312				print_ipv6_addr(ab, &sk->sk_v6_daddr,
313						inet->inet_dport,
314						"faddr", "fport");
315				break;
316			}
317#endif
318			case AF_UNIX:
319				u = unix_sk(sk);
320				addr = smp_load_acquire(&u->addr);
321				if (!addr)
322					break;
323				if (u->path.dentry) {
324					audit_log_d_path(ab, " path=", &u->path);
325					break;
326				}
327				len = addr->len-sizeof(short);
328				p = &addr->name->sun_path[0];
329				audit_log_format(ab, " path=");
330				if (*p)
331					audit_log_untrustedstring(ab, p);
332				else
333					audit_log_n_hex(ab, p, len);
334				break;
335			}
336		}
337
338		switch (a->u.net->family) {
339		case AF_INET:
340			print_ipv4_addr(ab, a->u.net->v4info.saddr,
341					a->u.net->sport,
342					"saddr", "src");
343			print_ipv4_addr(ab, a->u.net->v4info.daddr,
344					a->u.net->dport,
345					"daddr", "dest");
346			break;
347		case AF_INET6:
348			print_ipv6_addr(ab, &a->u.net->v6info.saddr,
349					a->u.net->sport,
350					"saddr", "src");
351			print_ipv6_addr(ab, &a->u.net->v6info.daddr,
352					a->u.net->dport,
353					"daddr", "dest");
354			break;
355		}
356		if (a->u.net->netif > 0) {
357			struct net_device *dev;
358
359			/* NOTE: we always use init's namespace */
360			dev = dev_get_by_index(&init_net, a->u.net->netif);
361			if (dev) {
362				audit_log_format(ab, " netif=%s", dev->name);
363				dev_put(dev);
364			}
365		}
366		break;
367#ifdef CONFIG_KEYS
368	case LSM_AUDIT_DATA_KEY:
369		audit_log_format(ab, " key_serial=%u", a->u.key_struct.key);
370		if (a->u.key_struct.key_desc) {
371			audit_log_format(ab, " key_desc=");
372			audit_log_untrustedstring(ab, a->u.key_struct.key_desc);
373		}
374		break;
375#endif
376	case LSM_AUDIT_DATA_KMOD:
377		audit_log_format(ab, " kmod=");
378		audit_log_untrustedstring(ab, a->u.kmod_name);
379		break;
380	case LSM_AUDIT_DATA_IBPKEY: {
381		struct in6_addr sbn_pfx;
382
383		memset(&sbn_pfx.s6_addr, 0,
384		       sizeof(sbn_pfx.s6_addr));
385		memcpy(&sbn_pfx.s6_addr, &a->u.ibpkey->subnet_prefix,
386		       sizeof(a->u.ibpkey->subnet_prefix));
387		audit_log_format(ab, " pkey=0x%x subnet_prefix=%pI6c",
388				 a->u.ibpkey->pkey, &sbn_pfx);
389		break;
390	}
391	case LSM_AUDIT_DATA_IBENDPORT:
392		audit_log_format(ab, " device=%s port_num=%u",
393				 a->u.ibendport->dev_name,
394				 a->u.ibendport->port);
395		break;
396	case LSM_AUDIT_DATA_LOCKDOWN:
397		audit_log_format(ab, " lockdown_reason=\"%s\"",
398				 lockdown_reasons[a->u.reason]);
399		break;
400	case LSM_AUDIT_DATA_ANONINODE:
401		audit_log_format(ab, " anonclass=%s", a->u.anonclass);
402		break;
403	case LSM_AUDIT_DATA_NLMSGTYPE:
404		audit_log_format(ab, " nl-msgtype=%hu", a->u.nlmsg_type);
405		break;
406	} /* switch (a->type) */
407}
408
409/**
410 * dump_common_audit_data - helper to dump common audit data
411 * @ab : the audit buffer
412 * @a : common audit data
413 */
414static void dump_common_audit_data(struct audit_buffer *ab,
415				   const struct common_audit_data *a)
416{
417	char comm[sizeof(current->comm)];
418
419	audit_log_format(ab, " pid=%d comm=", task_tgid_nr(current));
420	audit_log_untrustedstring(ab, get_task_comm(comm, current));
421	audit_log_lsm_data(ab, a);
422}
423
424/**
425 * common_lsm_audit - generic LSM auditing function
426 * @a:  auxiliary audit data
427 * @pre_audit: lsm-specific pre-audit callback
428 * @post_audit: lsm-specific post-audit callback
429 *
430 * setup the audit buffer for common security information
431 * uses callback to print LSM specific information
432 */
433void common_lsm_audit(struct common_audit_data *a,
434	void (*pre_audit)(struct audit_buffer *, void *),
435	void (*post_audit)(struct audit_buffer *, void *))
436{
437	struct audit_buffer *ab;
438
439	if (a == NULL)
440		return;
441	/* we use GFP_ATOMIC so we won't sleep */
442	ab = audit_log_start(audit_context(), GFP_ATOMIC | __GFP_NOWARN,
443			     AUDIT_AVC);
444
445	if (ab == NULL)
446		return;
447
448	if (pre_audit)
449		pre_audit(ab, a);
450
451	dump_common_audit_data(ab, a);
452
453	if (post_audit)
454		post_audit(ab, a);
455
456	audit_log_end(ab);
457}
~/ Read-only file preview.