1 // SPDX-License-Identifier: GPL-2.0-only
3 * common LSM auditing functions
5 * Based on code written for SELinux by :
6 * Stephen Smalley, <sds@tycho.nsa.gov>
7 * James Morris <jmorris@redhat.com>
8 * Author : Etienne Basset, <etienne.basset@ensta.org>
11 #include <linux/types.h>
12 #include <linux/stddef.h>
13 #include <linux/kernel.h>
14 #include <linux/gfp.h>
16 #include <linux/init.h>
19 #include <net/af_unix.h>
20 #include <linux/audit.h>
21 #include <linux/ipv6.h>
25 #include <linux/tcp.h>
26 #include <linux/udp.h>
27 #include <linux/dccp.h>
28 #include <linux/sctp.h>
29 #include <linux/lsm_audit.h>
30 #include <linux/security.h>
33 * ipv4_skb_to_auditdata : fill auditdata from skb
35 * @ad : the audit data to fill
36 * @proto : the layer 4 protocol
40 int ipv4_skb_to_auditdata(struct sk_buff
*skb
,
41 struct common_audit_data
*ad
, u8
*proto
)
47 ad
->u
.net
->v4info
.saddr
= ih
->saddr
;
48 ad
->u
.net
->v4info
.daddr
= ih
->daddr
;
51 *proto
= ih
->protocol
;
52 /* non initial fragment */
53 if (ntohs(ih
->frag_off
) & IP_OFFSET
)
56 switch (ih
->protocol
) {
58 struct tcphdr
*th
= tcp_hdr(skb
);
60 ad
->u
.net
->sport
= th
->source
;
61 ad
->u
.net
->dport
= th
->dest
;
65 struct udphdr
*uh
= udp_hdr(skb
);
67 ad
->u
.net
->sport
= uh
->source
;
68 ad
->u
.net
->dport
= uh
->dest
;
72 struct dccp_hdr
*dh
= dccp_hdr(skb
);
74 ad
->u
.net
->sport
= dh
->dccph_sport
;
75 ad
->u
.net
->dport
= dh
->dccph_dport
;
79 struct sctphdr
*sh
= sctp_hdr(skb
);
81 ad
->u
.net
->sport
= sh
->source
;
82 ad
->u
.net
->dport
= sh
->dest
;
90 #if IS_ENABLED(CONFIG_IPV6)
92 * ipv6_skb_to_auditdata : fill auditdata from skb
94 * @ad : the audit data to fill
95 * @proto : the layer 4 protocol
99 int ipv6_skb_to_auditdata(struct sk_buff
*skb
,
100 struct common_audit_data
*ad
, u8
*proto
)
108 ad
->u
.net
->v6info
.saddr
= ip6
->saddr
;
109 ad
->u
.net
->v6info
.daddr
= ip6
->daddr
;
110 /* IPv6 can have several extension header before the Transport header
112 offset
= skb_network_offset(skb
);
113 offset
+= sizeof(*ip6
);
114 nexthdr
= ip6
->nexthdr
;
115 offset
= ipv6_skip_exthdr(skb
, offset
, &nexthdr
, &frag_off
);
122 struct tcphdr _tcph
, *th
;
124 th
= skb_header_pointer(skb
, offset
, sizeof(_tcph
), &_tcph
);
128 ad
->u
.net
->sport
= th
->source
;
129 ad
->u
.net
->dport
= th
->dest
;
133 struct udphdr _udph
, *uh
;
135 uh
= skb_header_pointer(skb
, offset
, sizeof(_udph
), &_udph
);
139 ad
->u
.net
->sport
= uh
->source
;
140 ad
->u
.net
->dport
= uh
->dest
;
144 struct dccp_hdr _dccph
, *dh
;
146 dh
= skb_header_pointer(skb
, offset
, sizeof(_dccph
), &_dccph
);
150 ad
->u
.net
->sport
= dh
->dccph_sport
;
151 ad
->u
.net
->dport
= dh
->dccph_dport
;
155 struct sctphdr _sctph
, *sh
;
157 sh
= skb_header_pointer(skb
, offset
, sizeof(_sctph
), &_sctph
);
160 ad
->u
.net
->sport
= sh
->source
;
161 ad
->u
.net
->dport
= sh
->dest
;
172 static inline void print_ipv6_addr(struct audit_buffer
*ab
,
173 const struct in6_addr
*addr
, __be16 port
,
174 char *name1
, char *name2
)
176 if (!ipv6_addr_any(addr
))
177 audit_log_format(ab
, " %s=%pI6c", name1
, addr
);
179 audit_log_format(ab
, " %s=%d", name2
, ntohs(port
));
182 static inline void print_ipv4_addr(struct audit_buffer
*ab
, __be32 addr
,
183 __be16 port
, char *name1
, char *name2
)
186 audit_log_format(ab
, " %s=%pI4", name1
, &addr
);
188 audit_log_format(ab
, " %s=%d", name2
, ntohs(port
));
192 * dump_common_audit_data - helper to dump common audit data
193 * @ab : the audit buffer
194 * @a : common audit data
197 static void dump_common_audit_data(struct audit_buffer
*ab
,
198 struct common_audit_data
*a
)
200 char comm
[sizeof(current
->comm
)];
203 * To keep stack sizes in check force programmers to notice if they
204 * start making this union too large! See struct lsm_network_audit
205 * as an example of how to deal with large data.
207 BUILD_BUG_ON(sizeof(a
->u
) > sizeof(void *)*2);
209 audit_log_format(ab
, " pid=%d comm=", task_tgid_nr(current
));
210 audit_log_untrustedstring(ab
, memcpy(comm
, current
->comm
, sizeof(comm
)));
213 case LSM_AUDIT_DATA_NONE
:
215 case LSM_AUDIT_DATA_IPC
:
216 audit_log_format(ab
, " ipc_key=%d ", a
->u
.ipc_id
);
218 case LSM_AUDIT_DATA_CAP
:
219 audit_log_format(ab
, " capability=%d ", a
->u
.cap
);
221 case LSM_AUDIT_DATA_PATH
: {
224 audit_log_d_path(ab
, " path=", &a
->u
.path
);
226 inode
= d_backing_inode(a
->u
.path
.dentry
);
228 audit_log_format(ab
, " dev=");
229 audit_log_untrustedstring(ab
, inode
->i_sb
->s_id
);
230 audit_log_format(ab
, " ino=%lu", inode
->i_ino
);
234 case LSM_AUDIT_DATA_FILE
: {
237 audit_log_d_path(ab
, " path=", &a
->u
.file
->f_path
);
239 inode
= file_inode(a
->u
.file
);
241 audit_log_format(ab
, " dev=");
242 audit_log_untrustedstring(ab
, inode
->i_sb
->s_id
);
243 audit_log_format(ab
, " ino=%lu", inode
->i_ino
);
247 case LSM_AUDIT_DATA_IOCTL_OP
: {
250 audit_log_d_path(ab
, " path=", &a
->u
.op
->path
);
252 inode
= a
->u
.op
->path
.dentry
->d_inode
;
254 audit_log_format(ab
, " dev=");
255 audit_log_untrustedstring(ab
, inode
->i_sb
->s_id
);
256 audit_log_format(ab
, " ino=%lu", inode
->i_ino
);
259 audit_log_format(ab
, " ioctlcmd=0x%hx", a
->u
.op
->cmd
);
262 case LSM_AUDIT_DATA_DENTRY
: {
265 audit_log_format(ab
, " name=");
266 spin_lock(&a
->u
.dentry
->d_lock
);
267 audit_log_untrustedstring(ab
, a
->u
.dentry
->d_name
.name
);
268 spin_unlock(&a
->u
.dentry
->d_lock
);
270 inode
= d_backing_inode(a
->u
.dentry
);
272 audit_log_format(ab
, " dev=");
273 audit_log_untrustedstring(ab
, inode
->i_sb
->s_id
);
274 audit_log_format(ab
, " ino=%lu", inode
->i_ino
);
278 case LSM_AUDIT_DATA_INODE
: {
279 struct dentry
*dentry
;
284 dentry
= d_find_alias_rcu(inode
);
286 audit_log_format(ab
, " name=");
287 spin_lock(&dentry
->d_lock
);
288 audit_log_untrustedstring(ab
, dentry
->d_name
.name
);
289 spin_unlock(&dentry
->d_lock
);
291 audit_log_format(ab
, " dev=");
292 audit_log_untrustedstring(ab
, inode
->i_sb
->s_id
);
293 audit_log_format(ab
, " ino=%lu", inode
->i_ino
);
297 case LSM_AUDIT_DATA_TASK
: {
298 struct task_struct
*tsk
= a
->u
.tsk
;
300 pid_t pid
= task_tgid_nr(tsk
);
302 char comm
[sizeof(tsk
->comm
)];
303 audit_log_format(ab
, " opid=%d ocomm=", pid
);
304 audit_log_untrustedstring(ab
,
305 memcpy(comm
, tsk
->comm
, sizeof(comm
)));
310 case LSM_AUDIT_DATA_NET
:
312 const struct sock
*sk
= a
->u
.net
->sk
;
313 const struct unix_sock
*u
;
314 struct unix_address
*addr
;
318 switch (sk
->sk_family
) {
320 const struct inet_sock
*inet
= inet_sk(sk
);
322 print_ipv4_addr(ab
, inet
->inet_rcv_saddr
,
325 print_ipv4_addr(ab
, inet
->inet_daddr
,
330 #if IS_ENABLED(CONFIG_IPV6)
332 const struct inet_sock
*inet
= inet_sk(sk
);
334 print_ipv6_addr(ab
, &sk
->sk_v6_rcv_saddr
,
337 print_ipv6_addr(ab
, &sk
->sk_v6_daddr
,
345 addr
= smp_load_acquire(&u
->addr
);
348 if (u
->path
.dentry
) {
349 audit_log_d_path(ab
, " path=", &u
->path
);
352 len
= addr
->len
-sizeof(short);
353 p
= &addr
->name
->sun_path
[0];
354 audit_log_format(ab
, " path=");
356 audit_log_untrustedstring(ab
, p
);
358 audit_log_n_hex(ab
, p
, len
);
363 switch (a
->u
.net
->family
) {
365 print_ipv4_addr(ab
, a
->u
.net
->v4info
.saddr
,
368 print_ipv4_addr(ab
, a
->u
.net
->v4info
.daddr
,
373 print_ipv6_addr(ab
, &a
->u
.net
->v6info
.saddr
,
376 print_ipv6_addr(ab
, &a
->u
.net
->v6info
.daddr
,
381 if (a
->u
.net
->netif
> 0) {
382 struct net_device
*dev
;
384 /* NOTE: we always use init's namespace */
385 dev
= dev_get_by_index(&init_net
, a
->u
.net
->netif
);
387 audit_log_format(ab
, " netif=%s", dev
->name
);
393 case LSM_AUDIT_DATA_KEY
:
394 audit_log_format(ab
, " key_serial=%u", a
->u
.key_struct
.key
);
395 if (a
->u
.key_struct
.key_desc
) {
396 audit_log_format(ab
, " key_desc=");
397 audit_log_untrustedstring(ab
, a
->u
.key_struct
.key_desc
);
401 case LSM_AUDIT_DATA_KMOD
:
402 audit_log_format(ab
, " kmod=");
403 audit_log_untrustedstring(ab
, a
->u
.kmod_name
);
405 case LSM_AUDIT_DATA_IBPKEY
: {
406 struct in6_addr sbn_pfx
;
408 memset(&sbn_pfx
.s6_addr
, 0,
409 sizeof(sbn_pfx
.s6_addr
));
410 memcpy(&sbn_pfx
.s6_addr
, &a
->u
.ibpkey
->subnet_prefix
,
411 sizeof(a
->u
.ibpkey
->subnet_prefix
));
412 audit_log_format(ab
, " pkey=0x%x subnet_prefix=%pI6c",
413 a
->u
.ibpkey
->pkey
, &sbn_pfx
);
416 case LSM_AUDIT_DATA_IBENDPORT
:
417 audit_log_format(ab
, " device=%s port_num=%u",
418 a
->u
.ibendport
->dev_name
,
419 a
->u
.ibendport
->port
);
421 case LSM_AUDIT_DATA_LOCKDOWN
:
422 audit_log_format(ab
, " lockdown_reason=\"%s\"",
423 lockdown_reasons
[a
->u
.reason
]);
425 case LSM_AUDIT_DATA_ANONINODE
:
426 audit_log_format(ab
, " anonclass=%s", a
->u
.anonclass
);
428 } /* switch (a->type) */
432 * common_lsm_audit - generic LSM auditing function
433 * @a: auxiliary audit data
434 * @pre_audit: lsm-specific pre-audit callback
435 * @post_audit: lsm-specific post-audit callback
437 * setup the audit buffer for common security information
438 * uses callback to print LSM specific information
440 void common_lsm_audit(struct common_audit_data
*a
,
441 void (*pre_audit
)(struct audit_buffer
*, void *),
442 void (*post_audit
)(struct audit_buffer
*, void *))
444 struct audit_buffer
*ab
;
448 /* we use GFP_ATOMIC so we won't sleep */
449 ab
= audit_log_start(audit_context(), GFP_ATOMIC
| __GFP_NOWARN
,
458 dump_common_audit_data(ab
, a
);