16e837fb1SEtienne Basset /* 26e837fb1SEtienne Basset * common LSM auditing functions 36e837fb1SEtienne Basset * 46e837fb1SEtienne Basset * Based on code written for SELinux by : 56e837fb1SEtienne Basset * Stephen Smalley, <sds@epoch.ncsc.mil> 66e837fb1SEtienne Basset * James Morris <jmorris@redhat.com> 76e837fb1SEtienne Basset * Author : Etienne Basset, <etienne.basset@ensta.org> 86e837fb1SEtienne Basset * 96e837fb1SEtienne Basset * This program is free software; you can redistribute it and/or modify 106e837fb1SEtienne Basset * it under the terms of the GNU General Public License version 2, 116e837fb1SEtienne Basset * as published by the Free Software Foundation. 126e837fb1SEtienne Basset */ 136e837fb1SEtienne Basset 146e837fb1SEtienne Basset #include <linux/types.h> 156e837fb1SEtienne Basset #include <linux/stddef.h> 166e837fb1SEtienne Basset #include <linux/kernel.h> 175a0e3ad6STejun Heo #include <linux/gfp.h> 186e837fb1SEtienne Basset #include <linux/fs.h> 196e837fb1SEtienne Basset #include <linux/init.h> 206e837fb1SEtienne Basset #include <net/sock.h> 216e837fb1SEtienne Basset #include <linux/un.h> 226e837fb1SEtienne Basset #include <net/af_unix.h> 236e837fb1SEtienne Basset #include <linux/audit.h> 246e837fb1SEtienne Basset #include <linux/ipv6.h> 256e837fb1SEtienne Basset #include <linux/ip.h> 266e837fb1SEtienne Basset #include <net/ip.h> 276e837fb1SEtienne Basset #include <net/ipv6.h> 286e837fb1SEtienne Basset #include <linux/tcp.h> 296e837fb1SEtienne Basset #include <linux/udp.h> 306e837fb1SEtienne Basset #include <linux/dccp.h> 316e837fb1SEtienne Basset #include <linux/sctp.h> 326e837fb1SEtienne Basset #include <linux/lsm_audit.h> 336e837fb1SEtienne Basset 346e837fb1SEtienne Basset /** 356e837fb1SEtienne Basset * ipv4_skb_to_auditdata : fill auditdata from skb 366e837fb1SEtienne Basset * @skb : the skb 376e837fb1SEtienne Basset * @ad : the audit data to fill 386e837fb1SEtienne Basset * @proto : the layer 4 protocol 396e837fb1SEtienne Basset * 406e837fb1SEtienne Basset * return 0 on success 416e837fb1SEtienne Basset */ 426e837fb1SEtienne Basset int ipv4_skb_to_auditdata(struct sk_buff *skb, 436e837fb1SEtienne Basset struct common_audit_data *ad, u8 *proto) 446e837fb1SEtienne Basset { 456e837fb1SEtienne Basset int ret = 0; 466e837fb1SEtienne Basset struct iphdr *ih; 476e837fb1SEtienne Basset 486e837fb1SEtienne Basset ih = ip_hdr(skb); 496e837fb1SEtienne Basset if (ih == NULL) 506e837fb1SEtienne Basset return -EINVAL; 516e837fb1SEtienne Basset 5248c62af6SEric Paris ad->u.net->v4info.saddr = ih->saddr; 5348c62af6SEric Paris ad->u.net->v4info.daddr = ih->daddr; 546e837fb1SEtienne Basset 556e837fb1SEtienne Basset if (proto) 566e837fb1SEtienne Basset *proto = ih->protocol; 576e837fb1SEtienne Basset /* non initial fragment */ 586e837fb1SEtienne Basset if (ntohs(ih->frag_off) & IP_OFFSET) 596e837fb1SEtienne Basset return 0; 606e837fb1SEtienne Basset 616e837fb1SEtienne Basset switch (ih->protocol) { 626e837fb1SEtienne Basset case IPPROTO_TCP: { 636e837fb1SEtienne Basset struct tcphdr *th = tcp_hdr(skb); 646e837fb1SEtienne Basset if (th == NULL) 656e837fb1SEtienne Basset break; 666e837fb1SEtienne Basset 6748c62af6SEric Paris ad->u.net->sport = th->source; 6848c62af6SEric Paris ad->u.net->dport = th->dest; 696e837fb1SEtienne Basset break; 706e837fb1SEtienne Basset } 716e837fb1SEtienne Basset case IPPROTO_UDP: { 726e837fb1SEtienne Basset struct udphdr *uh = udp_hdr(skb); 736e837fb1SEtienne Basset if (uh == NULL) 746e837fb1SEtienne Basset break; 756e837fb1SEtienne Basset 7648c62af6SEric Paris ad->u.net->sport = uh->source; 7748c62af6SEric Paris ad->u.net->dport = uh->dest; 786e837fb1SEtienne Basset break; 796e837fb1SEtienne Basset } 806e837fb1SEtienne Basset case IPPROTO_DCCP: { 816e837fb1SEtienne Basset struct dccp_hdr *dh = dccp_hdr(skb); 826e837fb1SEtienne Basset if (dh == NULL) 836e837fb1SEtienne Basset break; 846e837fb1SEtienne Basset 8548c62af6SEric Paris ad->u.net->sport = dh->dccph_sport; 8648c62af6SEric Paris ad->u.net->dport = dh->dccph_dport; 876e837fb1SEtienne Basset break; 886e837fb1SEtienne Basset } 896e837fb1SEtienne Basset case IPPROTO_SCTP: { 906e837fb1SEtienne Basset struct sctphdr *sh = sctp_hdr(skb); 916e837fb1SEtienne Basset if (sh == NULL) 926e837fb1SEtienne Basset break; 9348c62af6SEric Paris ad->u.net->sport = sh->source; 9448c62af6SEric Paris ad->u.net->dport = sh->dest; 956e837fb1SEtienne Basset break; 966e837fb1SEtienne Basset } 976e837fb1SEtienne Basset default: 986e837fb1SEtienne Basset ret = -EINVAL; 996e837fb1SEtienne Basset } 1006e837fb1SEtienne Basset return ret; 1016e837fb1SEtienne Basset } 1021a93a6eaSJavier Martinez Canillas #if IS_ENABLED(CONFIG_IPV6) 1036e837fb1SEtienne Basset /** 1046e837fb1SEtienne Basset * ipv6_skb_to_auditdata : fill auditdata from skb 1056e837fb1SEtienne Basset * @skb : the skb 1066e837fb1SEtienne Basset * @ad : the audit data to fill 1076e837fb1SEtienne Basset * @proto : the layer 4 protocol 1086e837fb1SEtienne Basset * 1096e837fb1SEtienne Basset * return 0 on success 1106e837fb1SEtienne Basset */ 1116e837fb1SEtienne Basset int ipv6_skb_to_auditdata(struct sk_buff *skb, 1126e837fb1SEtienne Basset struct common_audit_data *ad, u8 *proto) 1136e837fb1SEtienne Basset { 1146e837fb1SEtienne Basset int offset, ret = 0; 1156e837fb1SEtienne Basset struct ipv6hdr *ip6; 1166e837fb1SEtienne Basset u8 nexthdr; 11775f2811cSJesse Gross __be16 frag_off; 1186e837fb1SEtienne Basset 1196e837fb1SEtienne Basset ip6 = ipv6_hdr(skb); 1206e837fb1SEtienne Basset if (ip6 == NULL) 1216e837fb1SEtienne Basset return -EINVAL; 12248c62af6SEric Paris ad->u.net->v6info.saddr = ip6->saddr; 12348c62af6SEric Paris ad->u.net->v6info.daddr = ip6->daddr; 1246e837fb1SEtienne Basset ret = 0; 1256e837fb1SEtienne Basset /* IPv6 can have several extension header before the Transport header 1266e837fb1SEtienne Basset * skip them */ 1276e837fb1SEtienne Basset offset = skb_network_offset(skb); 1286e837fb1SEtienne Basset offset += sizeof(*ip6); 1296e837fb1SEtienne Basset nexthdr = ip6->nexthdr; 13075f2811cSJesse Gross offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off); 1316e837fb1SEtienne Basset if (offset < 0) 1326e837fb1SEtienne Basset return 0; 1336e837fb1SEtienne Basset if (proto) 1346e837fb1SEtienne Basset *proto = nexthdr; 1356e837fb1SEtienne Basset switch (nexthdr) { 1366e837fb1SEtienne Basset case IPPROTO_TCP: { 1376e837fb1SEtienne Basset struct tcphdr _tcph, *th; 1386e837fb1SEtienne Basset 1396e837fb1SEtienne Basset th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph); 1406e837fb1SEtienne Basset if (th == NULL) 1416e837fb1SEtienne Basset break; 1426e837fb1SEtienne Basset 14348c62af6SEric Paris ad->u.net->sport = th->source; 14448c62af6SEric Paris ad->u.net->dport = th->dest; 1456e837fb1SEtienne Basset break; 1466e837fb1SEtienne Basset } 1476e837fb1SEtienne Basset case IPPROTO_UDP: { 1486e837fb1SEtienne Basset struct udphdr _udph, *uh; 1496e837fb1SEtienne Basset 1506e837fb1SEtienne Basset uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph); 1516e837fb1SEtienne Basset if (uh == NULL) 1526e837fb1SEtienne Basset break; 1536e837fb1SEtienne Basset 15448c62af6SEric Paris ad->u.net->sport = uh->source; 15548c62af6SEric Paris ad->u.net->dport = uh->dest; 1566e837fb1SEtienne Basset break; 1576e837fb1SEtienne Basset } 1586e837fb1SEtienne Basset case IPPROTO_DCCP: { 1596e837fb1SEtienne Basset struct dccp_hdr _dccph, *dh; 1606e837fb1SEtienne Basset 1616e837fb1SEtienne Basset dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph); 1626e837fb1SEtienne Basset if (dh == NULL) 1636e837fb1SEtienne Basset break; 1646e837fb1SEtienne Basset 16548c62af6SEric Paris ad->u.net->sport = dh->dccph_sport; 16648c62af6SEric Paris ad->u.net->dport = dh->dccph_dport; 1676e837fb1SEtienne Basset break; 1686e837fb1SEtienne Basset } 1696e837fb1SEtienne Basset case IPPROTO_SCTP: { 1706e837fb1SEtienne Basset struct sctphdr _sctph, *sh; 1716e837fb1SEtienne Basset 1726e837fb1SEtienne Basset sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph); 1736e837fb1SEtienne Basset if (sh == NULL) 1746e837fb1SEtienne Basset break; 17548c62af6SEric Paris ad->u.net->sport = sh->source; 17648c62af6SEric Paris ad->u.net->dport = sh->dest; 1776e837fb1SEtienne Basset break; 1786e837fb1SEtienne Basset } 1796e837fb1SEtienne Basset default: 1806e837fb1SEtienne Basset ret = -EINVAL; 1816e837fb1SEtienne Basset } 1826e837fb1SEtienne Basset return ret; 1836e837fb1SEtienne Basset } 1846e837fb1SEtienne Basset #endif 1856e837fb1SEtienne Basset 1866e837fb1SEtienne Basset 1876e837fb1SEtienne Basset static inline void print_ipv6_addr(struct audit_buffer *ab, 1886e837fb1SEtienne Basset struct in6_addr *addr, __be16 port, 1896e837fb1SEtienne Basset char *name1, char *name2) 1906e837fb1SEtienne Basset { 1916e837fb1SEtienne Basset if (!ipv6_addr_any(addr)) 192d8116591SPaul Moore audit_log_format(ab, " %s=%pI6c", name1, addr); 1936e837fb1SEtienne Basset if (port) 1946e837fb1SEtienne Basset audit_log_format(ab, " %s=%d", name2, ntohs(port)); 1956e837fb1SEtienne Basset } 1966e837fb1SEtienne Basset 1976e837fb1SEtienne Basset static inline void print_ipv4_addr(struct audit_buffer *ab, __be32 addr, 1986e837fb1SEtienne Basset __be16 port, char *name1, char *name2) 1996e837fb1SEtienne Basset { 2006e837fb1SEtienne Basset if (addr) 2016e837fb1SEtienne Basset audit_log_format(ab, " %s=%pI4", name1, &addr); 2026e837fb1SEtienne Basset if (port) 2036e837fb1SEtienne Basset audit_log_format(ab, " %s=%d", name2, ntohs(port)); 2046e837fb1SEtienne Basset } 2056e837fb1SEtienne Basset 2066e837fb1SEtienne Basset /** 2076e837fb1SEtienne Basset * dump_common_audit_data - helper to dump common audit data 2086e837fb1SEtienne Basset * @a : common audit data 2096e837fb1SEtienne Basset * 2106e837fb1SEtienne Basset */ 2116e837fb1SEtienne Basset static void dump_common_audit_data(struct audit_buffer *ab, 2126e837fb1SEtienne Basset struct common_audit_data *a) 2136e837fb1SEtienne Basset { 2145deeb5ceSRichard Guy Briggs char comm[sizeof(current->comm)]; 2156e837fb1SEtienne Basset 21607f62eb6SEric Paris /* 21707f62eb6SEric Paris * To keep stack sizes in check force programers to notice if they 21807f62eb6SEric Paris * start making this union too large! See struct lsm_network_audit 21907f62eb6SEric Paris * as an example of how to deal with large data. 22007f62eb6SEric Paris */ 22107f62eb6SEric Paris BUILD_BUG_ON(sizeof(a->u) > sizeof(void *)*2); 22207f62eb6SEric Paris 223fa2bea2fSPaul Moore audit_log_format(ab, " pid=%d comm=", task_tgid_nr(current)); 2245deeb5ceSRichard Guy Briggs audit_log_untrustedstring(ab, memcpy(comm, current->comm, sizeof(comm))); 2256e837fb1SEtienne Basset 2266e837fb1SEtienne Basset switch (a->type) { 227cb84aa9bSEric Paris case LSM_AUDIT_DATA_NONE: 2282bf49690SThomas Liu return; 2296e837fb1SEtienne Basset case LSM_AUDIT_DATA_IPC: 2306e837fb1SEtienne Basset audit_log_format(ab, " key=%d ", a->u.ipc_id); 2316e837fb1SEtienne Basset break; 2326e837fb1SEtienne Basset case LSM_AUDIT_DATA_CAP: 2336e837fb1SEtienne Basset audit_log_format(ab, " capability=%d ", a->u.cap); 2346e837fb1SEtienne Basset break; 235f48b7399SEric Paris case LSM_AUDIT_DATA_PATH: { 236f48b7399SEric Paris struct inode *inode; 237f48b7399SEric Paris 238f48b7399SEric Paris audit_log_d_path(ab, " path=", &a->u.path); 239a269434dSEric Paris 240c6f493d6SDavid Howells inode = d_backing_inode(a->u.path.dentry); 24141fdc305SKees Cook if (inode) { 24241fdc305SKees Cook audit_log_format(ab, " dev="); 24341fdc305SKees Cook audit_log_untrustedstring(ab, inode->i_sb->s_id); 24441fdc305SKees Cook audit_log_format(ab, " ino=%lu", inode->i_ino); 24541fdc305SKees Cook } 246a269434dSEric Paris break; 2476e837fb1SEtienne Basset } 24843af5de7SVivek Goyal case LSM_AUDIT_DATA_FILE: { 24943af5de7SVivek Goyal struct inode *inode; 25043af5de7SVivek Goyal 25143af5de7SVivek Goyal audit_log_d_path(ab, " path=", &a->u.file->f_path); 25243af5de7SVivek Goyal 25343af5de7SVivek Goyal inode = file_inode(a->u.file); 25443af5de7SVivek Goyal if (inode) { 25543af5de7SVivek Goyal audit_log_format(ab, " dev="); 25643af5de7SVivek Goyal audit_log_untrustedstring(ab, inode->i_sb->s_id); 25743af5de7SVivek Goyal audit_log_format(ab, " ino=%lu", inode->i_ino); 25843af5de7SVivek Goyal } 25943af5de7SVivek Goyal break; 26043af5de7SVivek Goyal } 261671a2781SJeff Vander Stoep case LSM_AUDIT_DATA_IOCTL_OP: { 262671a2781SJeff Vander Stoep struct inode *inode; 263671a2781SJeff Vander Stoep 264671a2781SJeff Vander Stoep audit_log_d_path(ab, " path=", &a->u.op->path); 265671a2781SJeff Vander Stoep 266671a2781SJeff Vander Stoep inode = a->u.op->path.dentry->d_inode; 267671a2781SJeff Vander Stoep if (inode) { 268671a2781SJeff Vander Stoep audit_log_format(ab, " dev="); 269671a2781SJeff Vander Stoep audit_log_untrustedstring(ab, inode->i_sb->s_id); 270671a2781SJeff Vander Stoep audit_log_format(ab, " ino=%lu", inode->i_ino); 271671a2781SJeff Vander Stoep } 272671a2781SJeff Vander Stoep 2738b31f456SWilliam Roberts audit_log_format(ab, " ioctlcmd=0x%hx", a->u.op->cmd); 274671a2781SJeff Vander Stoep break; 275671a2781SJeff Vander Stoep } 276a269434dSEric Paris case LSM_AUDIT_DATA_DENTRY: { 277a269434dSEric Paris struct inode *inode; 278a269434dSEric Paris 279a269434dSEric Paris audit_log_format(ab, " name="); 280a269434dSEric Paris audit_log_untrustedstring(ab, a->u.dentry->d_name.name); 281a269434dSEric Paris 282c6f493d6SDavid Howells inode = d_backing_inode(a->u.dentry); 28341fdc305SKees Cook if (inode) { 28441fdc305SKees Cook audit_log_format(ab, " dev="); 28541fdc305SKees Cook audit_log_untrustedstring(ab, inode->i_sb->s_id); 28641fdc305SKees Cook audit_log_format(ab, " ino=%lu", inode->i_ino); 28741fdc305SKees Cook } 288f48b7399SEric Paris break; 289f48b7399SEric Paris } 290f48b7399SEric Paris case LSM_AUDIT_DATA_INODE: { 2916e837fb1SEtienne Basset struct dentry *dentry; 292f48b7399SEric Paris struct inode *inode; 293f48b7399SEric Paris 294f48b7399SEric Paris inode = a->u.inode; 2956e837fb1SEtienne Basset dentry = d_find_alias(inode); 2966e837fb1SEtienne Basset if (dentry) { 2976e837fb1SEtienne Basset audit_log_format(ab, " name="); 2986e837fb1SEtienne Basset audit_log_untrustedstring(ab, 2996e837fb1SEtienne Basset dentry->d_name.name); 3006e837fb1SEtienne Basset dput(dentry); 3016e837fb1SEtienne Basset } 30241fdc305SKees Cook audit_log_format(ab, " dev="); 30341fdc305SKees Cook audit_log_untrustedstring(ab, inode->i_sb->s_id); 30441fdc305SKees Cook audit_log_format(ab, " ino=%lu", inode->i_ino); 3056e837fb1SEtienne Basset break; 306f48b7399SEric Paris } 3075deeb5ceSRichard Guy Briggs case LSM_AUDIT_DATA_TASK: { 3085deeb5ceSRichard Guy Briggs struct task_struct *tsk = a->u.tsk; 309f1dc4867SRichard Guy Briggs if (tsk) { 310fa2bea2fSPaul Moore pid_t pid = task_tgid_nr(tsk); 311f1dc4867SRichard Guy Briggs if (pid) { 3125deeb5ceSRichard Guy Briggs char comm[sizeof(tsk->comm)]; 3135c5bc97eSRichard Guy Briggs audit_log_format(ab, " opid=%d ocomm=", pid); 3145deeb5ceSRichard Guy Briggs audit_log_untrustedstring(ab, 3155deeb5ceSRichard Guy Briggs memcpy(comm, tsk->comm, sizeof(comm))); 3166e837fb1SEtienne Basset } 317f1dc4867SRichard Guy Briggs } 3186e837fb1SEtienne Basset break; 3195deeb5ceSRichard Guy Briggs } 3206e837fb1SEtienne Basset case LSM_AUDIT_DATA_NET: 32148c62af6SEric Paris if (a->u.net->sk) { 32248c62af6SEric Paris struct sock *sk = a->u.net->sk; 3236e837fb1SEtienne Basset struct unix_sock *u; 3246e837fb1SEtienne Basset int len = 0; 3256e837fb1SEtienne Basset char *p = NULL; 3266e837fb1SEtienne Basset 3276e837fb1SEtienne Basset switch (sk->sk_family) { 3286e837fb1SEtienne Basset case AF_INET: { 3296e837fb1SEtienne Basset struct inet_sock *inet = inet_sk(sk); 3306e837fb1SEtienne Basset 331c720c7e8SEric Dumazet print_ipv4_addr(ab, inet->inet_rcv_saddr, 332c720c7e8SEric Dumazet inet->inet_sport, 3336e837fb1SEtienne Basset "laddr", "lport"); 334c720c7e8SEric Dumazet print_ipv4_addr(ab, inet->inet_daddr, 335c720c7e8SEric Dumazet inet->inet_dport, 3366e837fb1SEtienne Basset "faddr", "fport"); 3376e837fb1SEtienne Basset break; 3386e837fb1SEtienne Basset } 339c2bb06dbSEric Dumazet #if IS_ENABLED(CONFIG_IPV6) 3406e837fb1SEtienne Basset case AF_INET6: { 3416e837fb1SEtienne Basset struct inet_sock *inet = inet_sk(sk); 3426e837fb1SEtienne Basset 343efe4208fSEric Dumazet print_ipv6_addr(ab, &sk->sk_v6_rcv_saddr, 344c720c7e8SEric Dumazet inet->inet_sport, 3456e837fb1SEtienne Basset "laddr", "lport"); 346efe4208fSEric Dumazet print_ipv6_addr(ab, &sk->sk_v6_daddr, 347c720c7e8SEric Dumazet inet->inet_dport, 3486e837fb1SEtienne Basset "faddr", "fport"); 3496e837fb1SEtienne Basset break; 3506e837fb1SEtienne Basset } 351c2bb06dbSEric Dumazet #endif 3526e837fb1SEtienne Basset case AF_UNIX: 3536e837fb1SEtienne Basset u = unix_sk(sk); 35440ffe67dSAl Viro if (u->path.dentry) { 35540ffe67dSAl Viro audit_log_d_path(ab, " path=", &u->path); 3566e837fb1SEtienne Basset break; 3576e837fb1SEtienne Basset } 3586e837fb1SEtienne Basset if (!u->addr) 3596e837fb1SEtienne Basset break; 3606e837fb1SEtienne Basset len = u->addr->len-sizeof(short); 3616e837fb1SEtienne Basset p = &u->addr->name->sun_path[0]; 3626e837fb1SEtienne Basset audit_log_format(ab, " path="); 3636e837fb1SEtienne Basset if (*p) 3646e837fb1SEtienne Basset audit_log_untrustedstring(ab, p); 3656e837fb1SEtienne Basset else 3666e837fb1SEtienne Basset audit_log_n_hex(ab, p, len); 3676e837fb1SEtienne Basset break; 3686e837fb1SEtienne Basset } 3696e837fb1SEtienne Basset } 3706e837fb1SEtienne Basset 37148c62af6SEric Paris switch (a->u.net->family) { 3726e837fb1SEtienne Basset case AF_INET: 37348c62af6SEric Paris print_ipv4_addr(ab, a->u.net->v4info.saddr, 37448c62af6SEric Paris a->u.net->sport, 3756e837fb1SEtienne Basset "saddr", "src"); 37648c62af6SEric Paris print_ipv4_addr(ab, a->u.net->v4info.daddr, 37748c62af6SEric Paris a->u.net->dport, 3786e837fb1SEtienne Basset "daddr", "dest"); 3796e837fb1SEtienne Basset break; 3806e837fb1SEtienne Basset case AF_INET6: 38148c62af6SEric Paris print_ipv6_addr(ab, &a->u.net->v6info.saddr, 38248c62af6SEric Paris a->u.net->sport, 3836e837fb1SEtienne Basset "saddr", "src"); 38448c62af6SEric Paris print_ipv6_addr(ab, &a->u.net->v6info.daddr, 38548c62af6SEric Paris a->u.net->dport, 3866e837fb1SEtienne Basset "daddr", "dest"); 3876e837fb1SEtienne Basset break; 3886e837fb1SEtienne Basset } 38948c62af6SEric Paris if (a->u.net->netif > 0) { 3906e837fb1SEtienne Basset struct net_device *dev; 3916e837fb1SEtienne Basset 3926e837fb1SEtienne Basset /* NOTE: we always use init's namespace */ 39348c62af6SEric Paris dev = dev_get_by_index(&init_net, a->u.net->netif); 3946e837fb1SEtienne Basset if (dev) { 3956e837fb1SEtienne Basset audit_log_format(ab, " netif=%s", dev->name); 3966e837fb1SEtienne Basset dev_put(dev); 3976e837fb1SEtienne Basset } 3986e837fb1SEtienne Basset } 3996e837fb1SEtienne Basset break; 4006e837fb1SEtienne Basset #ifdef CONFIG_KEYS 4016e837fb1SEtienne Basset case LSM_AUDIT_DATA_KEY: 4026e837fb1SEtienne Basset audit_log_format(ab, " key_serial=%u", a->u.key_struct.key); 4036e837fb1SEtienne Basset if (a->u.key_struct.key_desc) { 4046e837fb1SEtienne Basset audit_log_format(ab, " key_desc="); 4056e837fb1SEtienne Basset audit_log_untrustedstring(ab, a->u.key_struct.key_desc); 4066e837fb1SEtienne Basset } 4076e837fb1SEtienne Basset break; 4086e837fb1SEtienne Basset #endif 409dd8dbf2eSEric Paris case LSM_AUDIT_DATA_KMOD: 410dd8dbf2eSEric Paris audit_log_format(ab, " kmod="); 411dd8dbf2eSEric Paris audit_log_untrustedstring(ab, a->u.kmod_name); 412dd8dbf2eSEric Paris break; 413*cfc4d882SDaniel Jurgens case LSM_AUDIT_DATA_IBPKEY: { 414*cfc4d882SDaniel Jurgens struct in6_addr sbn_pfx; 415*cfc4d882SDaniel Jurgens 416*cfc4d882SDaniel Jurgens memset(&sbn_pfx.s6_addr, 0, 417*cfc4d882SDaniel Jurgens sizeof(sbn_pfx.s6_addr)); 418*cfc4d882SDaniel Jurgens memcpy(&sbn_pfx.s6_addr, &a->u.ibpkey->subnet_prefix, 419*cfc4d882SDaniel Jurgens sizeof(a->u.ibpkey->subnet_prefix)); 420*cfc4d882SDaniel Jurgens audit_log_format(ab, " pkey=0x%x subnet_prefix=%pI6c", 421*cfc4d882SDaniel Jurgens a->u.ibpkey->pkey, &sbn_pfx); 422*cfc4d882SDaniel Jurgens break; 423*cfc4d882SDaniel Jurgens } 4246e837fb1SEtienne Basset } /* switch (a->type) */ 4256e837fb1SEtienne Basset } 4266e837fb1SEtienne Basset 4276e837fb1SEtienne Basset /** 4286e837fb1SEtienne Basset * common_lsm_audit - generic LSM auditing function 4296e837fb1SEtienne Basset * @a: auxiliary audit data 430b61c37f5SLinus Torvalds * @pre_audit: lsm-specific pre-audit callback 431b61c37f5SLinus Torvalds * @post_audit: lsm-specific post-audit callback 4326e837fb1SEtienne Basset * 4336e837fb1SEtienne Basset * setup the audit buffer for common security information 4346e837fb1SEtienne Basset * uses callback to print LSM specific information 4356e837fb1SEtienne Basset */ 436b61c37f5SLinus Torvalds void common_lsm_audit(struct common_audit_data *a, 437b61c37f5SLinus Torvalds void (*pre_audit)(struct audit_buffer *, void *), 438b61c37f5SLinus Torvalds void (*post_audit)(struct audit_buffer *, void *)) 4396e837fb1SEtienne Basset { 4406e837fb1SEtienne Basset struct audit_buffer *ab; 4416e837fb1SEtienne Basset 4426e837fb1SEtienne Basset if (a == NULL) 4436e837fb1SEtienne Basset return; 4446e837fb1SEtienne Basset /* we use GFP_ATOMIC so we won't sleep */ 445a20b62bdSRichard Guy Briggs ab = audit_log_start(current->audit_context, GFP_ATOMIC | __GFP_NOWARN, 446a20b62bdSRichard Guy Briggs AUDIT_AVC); 4476e837fb1SEtienne Basset 4486e837fb1SEtienne Basset if (ab == NULL) 4496e837fb1SEtienne Basset return; 4506e837fb1SEtienne Basset 451b61c37f5SLinus Torvalds if (pre_audit) 452b61c37f5SLinus Torvalds pre_audit(ab, a); 4536e837fb1SEtienne Basset 4546e837fb1SEtienne Basset dump_common_audit_data(ab, a); 4556e837fb1SEtienne Basset 456b61c37f5SLinus Torvalds if (post_audit) 457b61c37f5SLinus Torvalds post_audit(ab, a); 4586e837fb1SEtienne Basset 4596e837fb1SEtienne Basset audit_log_end(ab); 4606e837fb1SEtienne Basset } 461