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