18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * common LSM auditing functions 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Based on code written for SELinux by : 68c2ecf20Sopenharmony_ci * Stephen Smalley, <sds@tycho.nsa.gov> 78c2ecf20Sopenharmony_ci * James Morris <jmorris@redhat.com> 88c2ecf20Sopenharmony_ci * Author : Etienne Basset, <etienne.basset@ensta.org> 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/types.h> 128c2ecf20Sopenharmony_ci#include <linux/stddef.h> 138c2ecf20Sopenharmony_ci#include <linux/kernel.h> 148c2ecf20Sopenharmony_ci#include <linux/gfp.h> 158c2ecf20Sopenharmony_ci#include <linux/fs.h> 168c2ecf20Sopenharmony_ci#include <linux/init.h> 178c2ecf20Sopenharmony_ci#include <net/sock.h> 188c2ecf20Sopenharmony_ci#include <linux/un.h> 198c2ecf20Sopenharmony_ci#include <net/af_unix.h> 208c2ecf20Sopenharmony_ci#include <linux/audit.h> 218c2ecf20Sopenharmony_ci#include <linux/ipv6.h> 228c2ecf20Sopenharmony_ci#include <linux/ip.h> 238c2ecf20Sopenharmony_ci#include <net/ip.h> 248c2ecf20Sopenharmony_ci#include <net/ipv6.h> 258c2ecf20Sopenharmony_ci#include <linux/tcp.h> 268c2ecf20Sopenharmony_ci#include <linux/udp.h> 278c2ecf20Sopenharmony_ci#include <linux/dccp.h> 288c2ecf20Sopenharmony_ci#include <linux/sctp.h> 298c2ecf20Sopenharmony_ci#include <linux/lsm_audit.h> 308c2ecf20Sopenharmony_ci#include <linux/security.h> 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci/** 338c2ecf20Sopenharmony_ci * ipv4_skb_to_auditdata : fill auditdata from skb 348c2ecf20Sopenharmony_ci * @skb : the skb 358c2ecf20Sopenharmony_ci * @ad : the audit data to fill 368c2ecf20Sopenharmony_ci * @proto : the layer 4 protocol 378c2ecf20Sopenharmony_ci * 388c2ecf20Sopenharmony_ci * return 0 on success 398c2ecf20Sopenharmony_ci */ 408c2ecf20Sopenharmony_ciint ipv4_skb_to_auditdata(struct sk_buff *skb, 418c2ecf20Sopenharmony_ci struct common_audit_data *ad, u8 *proto) 428c2ecf20Sopenharmony_ci{ 438c2ecf20Sopenharmony_ci int ret = 0; 448c2ecf20Sopenharmony_ci struct iphdr *ih; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci ih = ip_hdr(skb); 478c2ecf20Sopenharmony_ci if (ih == NULL) 488c2ecf20Sopenharmony_ci return -EINVAL; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci ad->u.net->v4info.saddr = ih->saddr; 518c2ecf20Sopenharmony_ci ad->u.net->v4info.daddr = ih->daddr; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci if (proto) 548c2ecf20Sopenharmony_ci *proto = ih->protocol; 558c2ecf20Sopenharmony_ci /* non initial fragment */ 568c2ecf20Sopenharmony_ci if (ntohs(ih->frag_off) & IP_OFFSET) 578c2ecf20Sopenharmony_ci return 0; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci switch (ih->protocol) { 608c2ecf20Sopenharmony_ci case IPPROTO_TCP: { 618c2ecf20Sopenharmony_ci struct tcphdr *th = tcp_hdr(skb); 628c2ecf20Sopenharmony_ci if (th == NULL) 638c2ecf20Sopenharmony_ci break; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci ad->u.net->sport = th->source; 668c2ecf20Sopenharmony_ci ad->u.net->dport = th->dest; 678c2ecf20Sopenharmony_ci break; 688c2ecf20Sopenharmony_ci } 698c2ecf20Sopenharmony_ci case IPPROTO_UDP: { 708c2ecf20Sopenharmony_ci struct udphdr *uh = udp_hdr(skb); 718c2ecf20Sopenharmony_ci if (uh == NULL) 728c2ecf20Sopenharmony_ci break; 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci ad->u.net->sport = uh->source; 758c2ecf20Sopenharmony_ci ad->u.net->dport = uh->dest; 768c2ecf20Sopenharmony_ci break; 778c2ecf20Sopenharmony_ci } 788c2ecf20Sopenharmony_ci case IPPROTO_DCCP: { 798c2ecf20Sopenharmony_ci struct dccp_hdr *dh = dccp_hdr(skb); 808c2ecf20Sopenharmony_ci if (dh == NULL) 818c2ecf20Sopenharmony_ci break; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci ad->u.net->sport = dh->dccph_sport; 848c2ecf20Sopenharmony_ci ad->u.net->dport = dh->dccph_dport; 858c2ecf20Sopenharmony_ci break; 868c2ecf20Sopenharmony_ci } 878c2ecf20Sopenharmony_ci case IPPROTO_SCTP: { 888c2ecf20Sopenharmony_ci struct sctphdr *sh = sctp_hdr(skb); 898c2ecf20Sopenharmony_ci if (sh == NULL) 908c2ecf20Sopenharmony_ci break; 918c2ecf20Sopenharmony_ci ad->u.net->sport = sh->source; 928c2ecf20Sopenharmony_ci ad->u.net->dport = sh->dest; 938c2ecf20Sopenharmony_ci break; 948c2ecf20Sopenharmony_ci } 958c2ecf20Sopenharmony_ci default: 968c2ecf20Sopenharmony_ci ret = -EINVAL; 978c2ecf20Sopenharmony_ci } 988c2ecf20Sopenharmony_ci return ret; 998c2ecf20Sopenharmony_ci} 1008c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6) 1018c2ecf20Sopenharmony_ci/** 1028c2ecf20Sopenharmony_ci * ipv6_skb_to_auditdata : fill auditdata from skb 1038c2ecf20Sopenharmony_ci * @skb : the skb 1048c2ecf20Sopenharmony_ci * @ad : the audit data to fill 1058c2ecf20Sopenharmony_ci * @proto : the layer 4 protocol 1068c2ecf20Sopenharmony_ci * 1078c2ecf20Sopenharmony_ci * return 0 on success 1088c2ecf20Sopenharmony_ci */ 1098c2ecf20Sopenharmony_ciint ipv6_skb_to_auditdata(struct sk_buff *skb, 1108c2ecf20Sopenharmony_ci struct common_audit_data *ad, u8 *proto) 1118c2ecf20Sopenharmony_ci{ 1128c2ecf20Sopenharmony_ci int offset, ret = 0; 1138c2ecf20Sopenharmony_ci struct ipv6hdr *ip6; 1148c2ecf20Sopenharmony_ci u8 nexthdr; 1158c2ecf20Sopenharmony_ci __be16 frag_off; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci ip6 = ipv6_hdr(skb); 1188c2ecf20Sopenharmony_ci if (ip6 == NULL) 1198c2ecf20Sopenharmony_ci return -EINVAL; 1208c2ecf20Sopenharmony_ci ad->u.net->v6info.saddr = ip6->saddr; 1218c2ecf20Sopenharmony_ci ad->u.net->v6info.daddr = ip6->daddr; 1228c2ecf20Sopenharmony_ci ret = 0; 1238c2ecf20Sopenharmony_ci /* IPv6 can have several extension header before the Transport header 1248c2ecf20Sopenharmony_ci * skip them */ 1258c2ecf20Sopenharmony_ci offset = skb_network_offset(skb); 1268c2ecf20Sopenharmony_ci offset += sizeof(*ip6); 1278c2ecf20Sopenharmony_ci nexthdr = ip6->nexthdr; 1288c2ecf20Sopenharmony_ci offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off); 1298c2ecf20Sopenharmony_ci if (offset < 0) 1308c2ecf20Sopenharmony_ci return 0; 1318c2ecf20Sopenharmony_ci if (proto) 1328c2ecf20Sopenharmony_ci *proto = nexthdr; 1338c2ecf20Sopenharmony_ci switch (nexthdr) { 1348c2ecf20Sopenharmony_ci case IPPROTO_TCP: { 1358c2ecf20Sopenharmony_ci struct tcphdr _tcph, *th; 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph); 1388c2ecf20Sopenharmony_ci if (th == NULL) 1398c2ecf20Sopenharmony_ci break; 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci ad->u.net->sport = th->source; 1428c2ecf20Sopenharmony_ci ad->u.net->dport = th->dest; 1438c2ecf20Sopenharmony_ci break; 1448c2ecf20Sopenharmony_ci } 1458c2ecf20Sopenharmony_ci case IPPROTO_UDP: { 1468c2ecf20Sopenharmony_ci struct udphdr _udph, *uh; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph); 1498c2ecf20Sopenharmony_ci if (uh == NULL) 1508c2ecf20Sopenharmony_ci break; 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci ad->u.net->sport = uh->source; 1538c2ecf20Sopenharmony_ci ad->u.net->dport = uh->dest; 1548c2ecf20Sopenharmony_ci break; 1558c2ecf20Sopenharmony_ci } 1568c2ecf20Sopenharmony_ci case IPPROTO_DCCP: { 1578c2ecf20Sopenharmony_ci struct dccp_hdr _dccph, *dh; 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph); 1608c2ecf20Sopenharmony_ci if (dh == NULL) 1618c2ecf20Sopenharmony_ci break; 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci ad->u.net->sport = dh->dccph_sport; 1648c2ecf20Sopenharmony_ci ad->u.net->dport = dh->dccph_dport; 1658c2ecf20Sopenharmony_ci break; 1668c2ecf20Sopenharmony_ci } 1678c2ecf20Sopenharmony_ci case IPPROTO_SCTP: { 1688c2ecf20Sopenharmony_ci struct sctphdr _sctph, *sh; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph); 1718c2ecf20Sopenharmony_ci if (sh == NULL) 1728c2ecf20Sopenharmony_ci break; 1738c2ecf20Sopenharmony_ci ad->u.net->sport = sh->source; 1748c2ecf20Sopenharmony_ci ad->u.net->dport = sh->dest; 1758c2ecf20Sopenharmony_ci break; 1768c2ecf20Sopenharmony_ci } 1778c2ecf20Sopenharmony_ci default: 1788c2ecf20Sopenharmony_ci ret = -EINVAL; 1798c2ecf20Sopenharmony_ci } 1808c2ecf20Sopenharmony_ci return ret; 1818c2ecf20Sopenharmony_ci} 1828c2ecf20Sopenharmony_ci#endif 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_cistatic inline void print_ipv6_addr(struct audit_buffer *ab, 1868c2ecf20Sopenharmony_ci struct in6_addr *addr, __be16 port, 1878c2ecf20Sopenharmony_ci char *name1, char *name2) 1888c2ecf20Sopenharmony_ci{ 1898c2ecf20Sopenharmony_ci if (!ipv6_addr_any(addr)) 1908c2ecf20Sopenharmony_ci audit_log_format(ab, " %s=%pI6c", name1, addr); 1918c2ecf20Sopenharmony_ci if (port) 1928c2ecf20Sopenharmony_ci audit_log_format(ab, " %s=%d", name2, ntohs(port)); 1938c2ecf20Sopenharmony_ci} 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_cistatic inline void print_ipv4_addr(struct audit_buffer *ab, __be32 addr, 1968c2ecf20Sopenharmony_ci __be16 port, char *name1, char *name2) 1978c2ecf20Sopenharmony_ci{ 1988c2ecf20Sopenharmony_ci if (addr) 1998c2ecf20Sopenharmony_ci audit_log_format(ab, " %s=%pI4", name1, &addr); 2008c2ecf20Sopenharmony_ci if (port) 2018c2ecf20Sopenharmony_ci audit_log_format(ab, " %s=%d", name2, ntohs(port)); 2028c2ecf20Sopenharmony_ci} 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci/** 2058c2ecf20Sopenharmony_ci * dump_common_audit_data - helper to dump common audit data 2068c2ecf20Sopenharmony_ci * @a : common audit data 2078c2ecf20Sopenharmony_ci * 2088c2ecf20Sopenharmony_ci */ 2098c2ecf20Sopenharmony_cistatic void dump_common_audit_data(struct audit_buffer *ab, 2108c2ecf20Sopenharmony_ci struct common_audit_data *a) 2118c2ecf20Sopenharmony_ci{ 2128c2ecf20Sopenharmony_ci char comm[sizeof(current->comm)]; 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci /* 2158c2ecf20Sopenharmony_ci * To keep stack sizes in check force programers to notice if they 2168c2ecf20Sopenharmony_ci * start making this union too large! See struct lsm_network_audit 2178c2ecf20Sopenharmony_ci * as an example of how to deal with large data. 2188c2ecf20Sopenharmony_ci */ 2198c2ecf20Sopenharmony_ci BUILD_BUG_ON(sizeof(a->u) > sizeof(void *)*2); 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci audit_log_format(ab, " pid=%d comm=", task_tgid_nr(current)); 2228c2ecf20Sopenharmony_ci audit_log_untrustedstring(ab, memcpy(comm, current->comm, sizeof(comm))); 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci switch (a->type) { 2258c2ecf20Sopenharmony_ci case LSM_AUDIT_DATA_NONE: 2268c2ecf20Sopenharmony_ci return; 2278c2ecf20Sopenharmony_ci case LSM_AUDIT_DATA_IPC: 2288c2ecf20Sopenharmony_ci audit_log_format(ab, " key=%d ", a->u.ipc_id); 2298c2ecf20Sopenharmony_ci break; 2308c2ecf20Sopenharmony_ci case LSM_AUDIT_DATA_CAP: 2318c2ecf20Sopenharmony_ci audit_log_format(ab, " capability=%d ", a->u.cap); 2328c2ecf20Sopenharmony_ci break; 2338c2ecf20Sopenharmony_ci case LSM_AUDIT_DATA_PATH: { 2348c2ecf20Sopenharmony_ci struct inode *inode; 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci audit_log_d_path(ab, " path=", &a->u.path); 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci inode = d_backing_inode(a->u.path.dentry); 2398c2ecf20Sopenharmony_ci if (inode) { 2408c2ecf20Sopenharmony_ci audit_log_format(ab, " dev="); 2418c2ecf20Sopenharmony_ci audit_log_untrustedstring(ab, inode->i_sb->s_id); 2428c2ecf20Sopenharmony_ci audit_log_format(ab, " ino=%lu", inode->i_ino); 2438c2ecf20Sopenharmony_ci } 2448c2ecf20Sopenharmony_ci audit_getcwd(); 2458c2ecf20Sopenharmony_ci break; 2468c2ecf20Sopenharmony_ci } 2478c2ecf20Sopenharmony_ci case LSM_AUDIT_DATA_FILE: { 2488c2ecf20Sopenharmony_ci struct inode *inode; 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci audit_log_d_path(ab, " path=", &a->u.file->f_path); 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci inode = file_inode(a->u.file); 2538c2ecf20Sopenharmony_ci if (inode) { 2548c2ecf20Sopenharmony_ci audit_log_format(ab, " dev="); 2558c2ecf20Sopenharmony_ci audit_log_untrustedstring(ab, inode->i_sb->s_id); 2568c2ecf20Sopenharmony_ci audit_log_format(ab, " ino=%lu", inode->i_ino); 2578c2ecf20Sopenharmony_ci } 2588c2ecf20Sopenharmony_ci audit_getcwd(); 2598c2ecf20Sopenharmony_ci break; 2608c2ecf20Sopenharmony_ci } 2618c2ecf20Sopenharmony_ci case LSM_AUDIT_DATA_IOCTL_OP: { 2628c2ecf20Sopenharmony_ci struct inode *inode; 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci audit_log_d_path(ab, " path=", &a->u.op->path); 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci inode = a->u.op->path.dentry->d_inode; 2678c2ecf20Sopenharmony_ci if (inode) { 2688c2ecf20Sopenharmony_ci audit_log_format(ab, " dev="); 2698c2ecf20Sopenharmony_ci audit_log_untrustedstring(ab, inode->i_sb->s_id); 2708c2ecf20Sopenharmony_ci audit_log_format(ab, " ino=%lu", inode->i_ino); 2718c2ecf20Sopenharmony_ci } 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_ci audit_log_format(ab, " ioctlcmd=0x%hx", a->u.op->cmd); 2748c2ecf20Sopenharmony_ci audit_getcwd(); 2758c2ecf20Sopenharmony_ci break; 2768c2ecf20Sopenharmony_ci } 2778c2ecf20Sopenharmony_ci case LSM_AUDIT_DATA_DENTRY: { 2788c2ecf20Sopenharmony_ci struct inode *inode; 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci audit_log_format(ab, " name="); 2818c2ecf20Sopenharmony_ci spin_lock(&a->u.dentry->d_lock); 2828c2ecf20Sopenharmony_ci audit_log_untrustedstring(ab, a->u.dentry->d_name.name); 2838c2ecf20Sopenharmony_ci spin_unlock(&a->u.dentry->d_lock); 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci inode = d_backing_inode(a->u.dentry); 2868c2ecf20Sopenharmony_ci if (inode) { 2878c2ecf20Sopenharmony_ci audit_log_format(ab, " dev="); 2888c2ecf20Sopenharmony_ci audit_log_untrustedstring(ab, inode->i_sb->s_id); 2898c2ecf20Sopenharmony_ci audit_log_format(ab, " ino=%lu", inode->i_ino); 2908c2ecf20Sopenharmony_ci } 2918c2ecf20Sopenharmony_ci audit_getcwd(); 2928c2ecf20Sopenharmony_ci break; 2938c2ecf20Sopenharmony_ci } 2948c2ecf20Sopenharmony_ci case LSM_AUDIT_DATA_INODE: { 2958c2ecf20Sopenharmony_ci struct dentry *dentry; 2968c2ecf20Sopenharmony_ci struct inode *inode; 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci inode = a->u.inode; 2998c2ecf20Sopenharmony_ci dentry = d_find_alias(inode); 3008c2ecf20Sopenharmony_ci if (dentry) { 3018c2ecf20Sopenharmony_ci audit_log_format(ab, " name="); 3028c2ecf20Sopenharmony_ci spin_lock(&dentry->d_lock); 3038c2ecf20Sopenharmony_ci audit_log_untrustedstring(ab, dentry->d_name.name); 3048c2ecf20Sopenharmony_ci spin_unlock(&dentry->d_lock); 3058c2ecf20Sopenharmony_ci dput(dentry); 3068c2ecf20Sopenharmony_ci } 3078c2ecf20Sopenharmony_ci audit_log_format(ab, " dev="); 3088c2ecf20Sopenharmony_ci audit_log_untrustedstring(ab, inode->i_sb->s_id); 3098c2ecf20Sopenharmony_ci audit_log_format(ab, " ino=%lu", inode->i_ino); 3108c2ecf20Sopenharmony_ci audit_getcwd(); 3118c2ecf20Sopenharmony_ci break; 3128c2ecf20Sopenharmony_ci } 3138c2ecf20Sopenharmony_ci case LSM_AUDIT_DATA_TASK: { 3148c2ecf20Sopenharmony_ci struct task_struct *tsk = a->u.tsk; 3158c2ecf20Sopenharmony_ci if (tsk) { 3168c2ecf20Sopenharmony_ci pid_t pid = task_tgid_nr(tsk); 3178c2ecf20Sopenharmony_ci if (pid) { 3188c2ecf20Sopenharmony_ci char comm[sizeof(tsk->comm)]; 3198c2ecf20Sopenharmony_ci audit_log_format(ab, " opid=%d ocomm=", pid); 3208c2ecf20Sopenharmony_ci audit_log_untrustedstring(ab, 3218c2ecf20Sopenharmony_ci memcpy(comm, tsk->comm, sizeof(comm))); 3228c2ecf20Sopenharmony_ci } 3238c2ecf20Sopenharmony_ci } 3248c2ecf20Sopenharmony_ci break; 3258c2ecf20Sopenharmony_ci } 3268c2ecf20Sopenharmony_ci case LSM_AUDIT_DATA_NET: 3278c2ecf20Sopenharmony_ci if (a->u.net->sk) { 3288c2ecf20Sopenharmony_ci struct sock *sk = a->u.net->sk; 3298c2ecf20Sopenharmony_ci struct unix_sock *u; 3308c2ecf20Sopenharmony_ci struct unix_address *addr; 3318c2ecf20Sopenharmony_ci int len = 0; 3328c2ecf20Sopenharmony_ci char *p = NULL; 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_ci switch (sk->sk_family) { 3358c2ecf20Sopenharmony_ci case AF_INET: { 3368c2ecf20Sopenharmony_ci struct inet_sock *inet = inet_sk(sk); 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_ci print_ipv4_addr(ab, inet->inet_rcv_saddr, 3398c2ecf20Sopenharmony_ci inet->inet_sport, 3408c2ecf20Sopenharmony_ci "laddr", "lport"); 3418c2ecf20Sopenharmony_ci print_ipv4_addr(ab, inet->inet_daddr, 3428c2ecf20Sopenharmony_ci inet->inet_dport, 3438c2ecf20Sopenharmony_ci "faddr", "fport"); 3448c2ecf20Sopenharmony_ci break; 3458c2ecf20Sopenharmony_ci } 3468c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6) 3478c2ecf20Sopenharmony_ci case AF_INET6: { 3488c2ecf20Sopenharmony_ci struct inet_sock *inet = inet_sk(sk); 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ci print_ipv6_addr(ab, &sk->sk_v6_rcv_saddr, 3518c2ecf20Sopenharmony_ci inet->inet_sport, 3528c2ecf20Sopenharmony_ci "laddr", "lport"); 3538c2ecf20Sopenharmony_ci print_ipv6_addr(ab, &sk->sk_v6_daddr, 3548c2ecf20Sopenharmony_ci inet->inet_dport, 3558c2ecf20Sopenharmony_ci "faddr", "fport"); 3568c2ecf20Sopenharmony_ci break; 3578c2ecf20Sopenharmony_ci } 3588c2ecf20Sopenharmony_ci#endif 3598c2ecf20Sopenharmony_ci case AF_UNIX: 3608c2ecf20Sopenharmony_ci u = unix_sk(sk); 3618c2ecf20Sopenharmony_ci addr = smp_load_acquire(&u->addr); 3628c2ecf20Sopenharmony_ci if (!addr) 3638c2ecf20Sopenharmony_ci break; 3648c2ecf20Sopenharmony_ci if (u->path.dentry) { 3658c2ecf20Sopenharmony_ci audit_log_d_path(ab, " path=", &u->path); 3668c2ecf20Sopenharmony_ci break; 3678c2ecf20Sopenharmony_ci } 3688c2ecf20Sopenharmony_ci len = addr->len-sizeof(short); 3698c2ecf20Sopenharmony_ci p = &addr->name->sun_path[0]; 3708c2ecf20Sopenharmony_ci audit_log_format(ab, " path="); 3718c2ecf20Sopenharmony_ci if (*p) 3728c2ecf20Sopenharmony_ci audit_log_untrustedstring(ab, p); 3738c2ecf20Sopenharmony_ci else 3748c2ecf20Sopenharmony_ci audit_log_n_hex(ab, p, len); 3758c2ecf20Sopenharmony_ci break; 3768c2ecf20Sopenharmony_ci } 3778c2ecf20Sopenharmony_ci } 3788c2ecf20Sopenharmony_ci 3798c2ecf20Sopenharmony_ci switch (a->u.net->family) { 3808c2ecf20Sopenharmony_ci case AF_INET: 3818c2ecf20Sopenharmony_ci print_ipv4_addr(ab, a->u.net->v4info.saddr, 3828c2ecf20Sopenharmony_ci a->u.net->sport, 3838c2ecf20Sopenharmony_ci "saddr", "src"); 3848c2ecf20Sopenharmony_ci print_ipv4_addr(ab, a->u.net->v4info.daddr, 3858c2ecf20Sopenharmony_ci a->u.net->dport, 3868c2ecf20Sopenharmony_ci "daddr", "dest"); 3878c2ecf20Sopenharmony_ci break; 3888c2ecf20Sopenharmony_ci case AF_INET6: 3898c2ecf20Sopenharmony_ci print_ipv6_addr(ab, &a->u.net->v6info.saddr, 3908c2ecf20Sopenharmony_ci a->u.net->sport, 3918c2ecf20Sopenharmony_ci "saddr", "src"); 3928c2ecf20Sopenharmony_ci print_ipv6_addr(ab, &a->u.net->v6info.daddr, 3938c2ecf20Sopenharmony_ci a->u.net->dport, 3948c2ecf20Sopenharmony_ci "daddr", "dest"); 3958c2ecf20Sopenharmony_ci break; 3968c2ecf20Sopenharmony_ci } 3978c2ecf20Sopenharmony_ci if (a->u.net->netif > 0) { 3988c2ecf20Sopenharmony_ci struct net_device *dev; 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_ci /* NOTE: we always use init's namespace */ 4018c2ecf20Sopenharmony_ci dev = dev_get_by_index(&init_net, a->u.net->netif); 4028c2ecf20Sopenharmony_ci if (dev) { 4038c2ecf20Sopenharmony_ci audit_log_format(ab, " netif=%s", dev->name); 4048c2ecf20Sopenharmony_ci dev_put(dev); 4058c2ecf20Sopenharmony_ci } 4068c2ecf20Sopenharmony_ci } 4078c2ecf20Sopenharmony_ci break; 4088c2ecf20Sopenharmony_ci#ifdef CONFIG_KEYS 4098c2ecf20Sopenharmony_ci case LSM_AUDIT_DATA_KEY: 4108c2ecf20Sopenharmony_ci audit_log_format(ab, " key_serial=%u", a->u.key_struct.key); 4118c2ecf20Sopenharmony_ci if (a->u.key_struct.key_desc) { 4128c2ecf20Sopenharmony_ci audit_log_format(ab, " key_desc="); 4138c2ecf20Sopenharmony_ci audit_log_untrustedstring(ab, a->u.key_struct.key_desc); 4148c2ecf20Sopenharmony_ci } 4158c2ecf20Sopenharmony_ci break; 4168c2ecf20Sopenharmony_ci#endif 4178c2ecf20Sopenharmony_ci case LSM_AUDIT_DATA_KMOD: 4188c2ecf20Sopenharmony_ci audit_log_format(ab, " kmod="); 4198c2ecf20Sopenharmony_ci audit_log_untrustedstring(ab, a->u.kmod_name); 4208c2ecf20Sopenharmony_ci break; 4218c2ecf20Sopenharmony_ci case LSM_AUDIT_DATA_IBPKEY: { 4228c2ecf20Sopenharmony_ci struct in6_addr sbn_pfx; 4238c2ecf20Sopenharmony_ci 4248c2ecf20Sopenharmony_ci memset(&sbn_pfx.s6_addr, 0, 4258c2ecf20Sopenharmony_ci sizeof(sbn_pfx.s6_addr)); 4268c2ecf20Sopenharmony_ci memcpy(&sbn_pfx.s6_addr, &a->u.ibpkey->subnet_prefix, 4278c2ecf20Sopenharmony_ci sizeof(a->u.ibpkey->subnet_prefix)); 4288c2ecf20Sopenharmony_ci audit_log_format(ab, " pkey=0x%x subnet_prefix=%pI6c", 4298c2ecf20Sopenharmony_ci a->u.ibpkey->pkey, &sbn_pfx); 4308c2ecf20Sopenharmony_ci break; 4318c2ecf20Sopenharmony_ci } 4328c2ecf20Sopenharmony_ci case LSM_AUDIT_DATA_IBENDPORT: 4338c2ecf20Sopenharmony_ci audit_log_format(ab, " device=%s port_num=%u", 4348c2ecf20Sopenharmony_ci a->u.ibendport->dev_name, 4358c2ecf20Sopenharmony_ci a->u.ibendport->port); 4368c2ecf20Sopenharmony_ci break; 4378c2ecf20Sopenharmony_ci case LSM_AUDIT_DATA_LOCKDOWN: 4388c2ecf20Sopenharmony_ci audit_log_format(ab, " lockdown_reason=\"%s\"", 4398c2ecf20Sopenharmony_ci lockdown_reasons[a->u.reason]); 4408c2ecf20Sopenharmony_ci break; 4418c2ecf20Sopenharmony_ci } /* switch (a->type) */ 4428c2ecf20Sopenharmony_ci} 4438c2ecf20Sopenharmony_ci 4448c2ecf20Sopenharmony_ci/** 4458c2ecf20Sopenharmony_ci * common_lsm_audit - generic LSM auditing function 4468c2ecf20Sopenharmony_ci * @a: auxiliary audit data 4478c2ecf20Sopenharmony_ci * @pre_audit: lsm-specific pre-audit callback 4488c2ecf20Sopenharmony_ci * @post_audit: lsm-specific post-audit callback 4498c2ecf20Sopenharmony_ci * 4508c2ecf20Sopenharmony_ci * setup the audit buffer for common security information 4518c2ecf20Sopenharmony_ci * uses callback to print LSM specific information 4528c2ecf20Sopenharmony_ci */ 4538c2ecf20Sopenharmony_civoid common_lsm_audit(struct common_audit_data *a, 4548c2ecf20Sopenharmony_ci void (*pre_audit)(struct audit_buffer *, void *), 4558c2ecf20Sopenharmony_ci void (*post_audit)(struct audit_buffer *, void *)) 4568c2ecf20Sopenharmony_ci{ 4578c2ecf20Sopenharmony_ci struct audit_buffer *ab; 4588c2ecf20Sopenharmony_ci 4598c2ecf20Sopenharmony_ci if (a == NULL) 4608c2ecf20Sopenharmony_ci return; 4618c2ecf20Sopenharmony_ci /* we use GFP_ATOMIC so we won't sleep */ 4628c2ecf20Sopenharmony_ci ab = audit_log_start(audit_context(), GFP_ATOMIC | __GFP_NOWARN, 4638c2ecf20Sopenharmony_ci AUDIT_AVC); 4648c2ecf20Sopenharmony_ci 4658c2ecf20Sopenharmony_ci if (ab == NULL) 4668c2ecf20Sopenharmony_ci return; 4678c2ecf20Sopenharmony_ci 4688c2ecf20Sopenharmony_ci if (pre_audit) 4698c2ecf20Sopenharmony_ci pre_audit(ab, a); 4708c2ecf20Sopenharmony_ci 4718c2ecf20Sopenharmony_ci dump_common_audit_data(ab, a); 4728c2ecf20Sopenharmony_ci 4738c2ecf20Sopenharmony_ci if (post_audit) 4748c2ecf20Sopenharmony_ci post_audit(ab, a); 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_ci audit_log_end(ab); 4778c2ecf20Sopenharmony_ci} 478