162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * common LSM auditing functions 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Based on code written for SELinux by : 662306a36Sopenharmony_ci * Stephen Smalley, <sds@tycho.nsa.gov> 762306a36Sopenharmony_ci * James Morris <jmorris@redhat.com> 862306a36Sopenharmony_ci * Author : Etienne Basset, <etienne.basset@ensta.org> 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/types.h> 1262306a36Sopenharmony_ci#include <linux/stddef.h> 1362306a36Sopenharmony_ci#include <linux/kernel.h> 1462306a36Sopenharmony_ci#include <linux/gfp.h> 1562306a36Sopenharmony_ci#include <linux/fs.h> 1662306a36Sopenharmony_ci#include <linux/init.h> 1762306a36Sopenharmony_ci#include <net/sock.h> 1862306a36Sopenharmony_ci#include <linux/un.h> 1962306a36Sopenharmony_ci#include <net/af_unix.h> 2062306a36Sopenharmony_ci#include <linux/audit.h> 2162306a36Sopenharmony_ci#include <linux/ipv6.h> 2262306a36Sopenharmony_ci#include <linux/ip.h> 2362306a36Sopenharmony_ci#include <net/ip.h> 2462306a36Sopenharmony_ci#include <net/ipv6.h> 2562306a36Sopenharmony_ci#include <linux/tcp.h> 2662306a36Sopenharmony_ci#include <linux/udp.h> 2762306a36Sopenharmony_ci#include <linux/dccp.h> 2862306a36Sopenharmony_ci#include <linux/sctp.h> 2962306a36Sopenharmony_ci#include <linux/lsm_audit.h> 3062306a36Sopenharmony_ci#include <linux/security.h> 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci/** 3362306a36Sopenharmony_ci * ipv4_skb_to_auditdata : fill auditdata from skb 3462306a36Sopenharmony_ci * @skb : the skb 3562306a36Sopenharmony_ci * @ad : the audit data to fill 3662306a36Sopenharmony_ci * @proto : the layer 4 protocol 3762306a36Sopenharmony_ci * 3862306a36Sopenharmony_ci * return 0 on success 3962306a36Sopenharmony_ci */ 4062306a36Sopenharmony_ciint ipv4_skb_to_auditdata(struct sk_buff *skb, 4162306a36Sopenharmony_ci struct common_audit_data *ad, u8 *proto) 4262306a36Sopenharmony_ci{ 4362306a36Sopenharmony_ci int ret = 0; 4462306a36Sopenharmony_ci struct iphdr *ih; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci ih = ip_hdr(skb); 4762306a36Sopenharmony_ci ad->u.net->v4info.saddr = ih->saddr; 4862306a36Sopenharmony_ci ad->u.net->v4info.daddr = ih->daddr; 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci if (proto) 5162306a36Sopenharmony_ci *proto = ih->protocol; 5262306a36Sopenharmony_ci /* non initial fragment */ 5362306a36Sopenharmony_ci if (ntohs(ih->frag_off) & IP_OFFSET) 5462306a36Sopenharmony_ci return 0; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci switch (ih->protocol) { 5762306a36Sopenharmony_ci case IPPROTO_TCP: { 5862306a36Sopenharmony_ci struct tcphdr *th = tcp_hdr(skb); 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci ad->u.net->sport = th->source; 6162306a36Sopenharmony_ci ad->u.net->dport = th->dest; 6262306a36Sopenharmony_ci break; 6362306a36Sopenharmony_ci } 6462306a36Sopenharmony_ci case IPPROTO_UDP: { 6562306a36Sopenharmony_ci struct udphdr *uh = udp_hdr(skb); 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci ad->u.net->sport = uh->source; 6862306a36Sopenharmony_ci ad->u.net->dport = uh->dest; 6962306a36Sopenharmony_ci break; 7062306a36Sopenharmony_ci } 7162306a36Sopenharmony_ci case IPPROTO_DCCP: { 7262306a36Sopenharmony_ci struct dccp_hdr *dh = dccp_hdr(skb); 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci ad->u.net->sport = dh->dccph_sport; 7562306a36Sopenharmony_ci ad->u.net->dport = dh->dccph_dport; 7662306a36Sopenharmony_ci break; 7762306a36Sopenharmony_ci } 7862306a36Sopenharmony_ci case IPPROTO_SCTP: { 7962306a36Sopenharmony_ci struct sctphdr *sh = sctp_hdr(skb); 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci ad->u.net->sport = sh->source; 8262306a36Sopenharmony_ci ad->u.net->dport = sh->dest; 8362306a36Sopenharmony_ci break; 8462306a36Sopenharmony_ci } 8562306a36Sopenharmony_ci default: 8662306a36Sopenharmony_ci ret = -EINVAL; 8762306a36Sopenharmony_ci } 8862306a36Sopenharmony_ci return ret; 8962306a36Sopenharmony_ci} 9062306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6) 9162306a36Sopenharmony_ci/** 9262306a36Sopenharmony_ci * ipv6_skb_to_auditdata : fill auditdata from skb 9362306a36Sopenharmony_ci * @skb : the skb 9462306a36Sopenharmony_ci * @ad : the audit data to fill 9562306a36Sopenharmony_ci * @proto : the layer 4 protocol 9662306a36Sopenharmony_ci * 9762306a36Sopenharmony_ci * return 0 on success 9862306a36Sopenharmony_ci */ 9962306a36Sopenharmony_ciint ipv6_skb_to_auditdata(struct sk_buff *skb, 10062306a36Sopenharmony_ci struct common_audit_data *ad, u8 *proto) 10162306a36Sopenharmony_ci{ 10262306a36Sopenharmony_ci int offset, ret = 0; 10362306a36Sopenharmony_ci struct ipv6hdr *ip6; 10462306a36Sopenharmony_ci u8 nexthdr; 10562306a36Sopenharmony_ci __be16 frag_off; 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci ip6 = ipv6_hdr(skb); 10862306a36Sopenharmony_ci ad->u.net->v6info.saddr = ip6->saddr; 10962306a36Sopenharmony_ci ad->u.net->v6info.daddr = ip6->daddr; 11062306a36Sopenharmony_ci /* IPv6 can have several extension header before the Transport header 11162306a36Sopenharmony_ci * skip them */ 11262306a36Sopenharmony_ci offset = skb_network_offset(skb); 11362306a36Sopenharmony_ci offset += sizeof(*ip6); 11462306a36Sopenharmony_ci nexthdr = ip6->nexthdr; 11562306a36Sopenharmony_ci offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off); 11662306a36Sopenharmony_ci if (offset < 0) 11762306a36Sopenharmony_ci return 0; 11862306a36Sopenharmony_ci if (proto) 11962306a36Sopenharmony_ci *proto = nexthdr; 12062306a36Sopenharmony_ci switch (nexthdr) { 12162306a36Sopenharmony_ci case IPPROTO_TCP: { 12262306a36Sopenharmony_ci struct tcphdr _tcph, *th; 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph); 12562306a36Sopenharmony_ci if (th == NULL) 12662306a36Sopenharmony_ci break; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci ad->u.net->sport = th->source; 12962306a36Sopenharmony_ci ad->u.net->dport = th->dest; 13062306a36Sopenharmony_ci break; 13162306a36Sopenharmony_ci } 13262306a36Sopenharmony_ci case IPPROTO_UDP: { 13362306a36Sopenharmony_ci struct udphdr _udph, *uh; 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph); 13662306a36Sopenharmony_ci if (uh == NULL) 13762306a36Sopenharmony_ci break; 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci ad->u.net->sport = uh->source; 14062306a36Sopenharmony_ci ad->u.net->dport = uh->dest; 14162306a36Sopenharmony_ci break; 14262306a36Sopenharmony_ci } 14362306a36Sopenharmony_ci case IPPROTO_DCCP: { 14462306a36Sopenharmony_ci struct dccp_hdr _dccph, *dh; 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph); 14762306a36Sopenharmony_ci if (dh == NULL) 14862306a36Sopenharmony_ci break; 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci ad->u.net->sport = dh->dccph_sport; 15162306a36Sopenharmony_ci ad->u.net->dport = dh->dccph_dport; 15262306a36Sopenharmony_ci break; 15362306a36Sopenharmony_ci } 15462306a36Sopenharmony_ci case IPPROTO_SCTP: { 15562306a36Sopenharmony_ci struct sctphdr _sctph, *sh; 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph); 15862306a36Sopenharmony_ci if (sh == NULL) 15962306a36Sopenharmony_ci break; 16062306a36Sopenharmony_ci ad->u.net->sport = sh->source; 16162306a36Sopenharmony_ci ad->u.net->dport = sh->dest; 16262306a36Sopenharmony_ci break; 16362306a36Sopenharmony_ci } 16462306a36Sopenharmony_ci default: 16562306a36Sopenharmony_ci ret = -EINVAL; 16662306a36Sopenharmony_ci } 16762306a36Sopenharmony_ci return ret; 16862306a36Sopenharmony_ci} 16962306a36Sopenharmony_ci#endif 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_cistatic inline void print_ipv6_addr(struct audit_buffer *ab, 17362306a36Sopenharmony_ci const struct in6_addr *addr, __be16 port, 17462306a36Sopenharmony_ci char *name1, char *name2) 17562306a36Sopenharmony_ci{ 17662306a36Sopenharmony_ci if (!ipv6_addr_any(addr)) 17762306a36Sopenharmony_ci audit_log_format(ab, " %s=%pI6c", name1, addr); 17862306a36Sopenharmony_ci if (port) 17962306a36Sopenharmony_ci audit_log_format(ab, " %s=%d", name2, ntohs(port)); 18062306a36Sopenharmony_ci} 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_cistatic inline void print_ipv4_addr(struct audit_buffer *ab, __be32 addr, 18362306a36Sopenharmony_ci __be16 port, char *name1, char *name2) 18462306a36Sopenharmony_ci{ 18562306a36Sopenharmony_ci if (addr) 18662306a36Sopenharmony_ci audit_log_format(ab, " %s=%pI4", name1, &addr); 18762306a36Sopenharmony_ci if (port) 18862306a36Sopenharmony_ci audit_log_format(ab, " %s=%d", name2, ntohs(port)); 18962306a36Sopenharmony_ci} 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci/** 19262306a36Sopenharmony_ci * dump_common_audit_data - helper to dump common audit data 19362306a36Sopenharmony_ci * @ab : the audit buffer 19462306a36Sopenharmony_ci * @a : common audit data 19562306a36Sopenharmony_ci * 19662306a36Sopenharmony_ci */ 19762306a36Sopenharmony_cistatic void dump_common_audit_data(struct audit_buffer *ab, 19862306a36Sopenharmony_ci struct common_audit_data *a) 19962306a36Sopenharmony_ci{ 20062306a36Sopenharmony_ci char comm[sizeof(current->comm)]; 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci /* 20362306a36Sopenharmony_ci * To keep stack sizes in check force programmers to notice if they 20462306a36Sopenharmony_ci * start making this union too large! See struct lsm_network_audit 20562306a36Sopenharmony_ci * as an example of how to deal with large data. 20662306a36Sopenharmony_ci */ 20762306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(a->u) > sizeof(void *)*2); 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci audit_log_format(ab, " pid=%d comm=", task_tgid_nr(current)); 21062306a36Sopenharmony_ci audit_log_untrustedstring(ab, memcpy(comm, current->comm, sizeof(comm))); 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci switch (a->type) { 21362306a36Sopenharmony_ci case LSM_AUDIT_DATA_NONE: 21462306a36Sopenharmony_ci return; 21562306a36Sopenharmony_ci case LSM_AUDIT_DATA_IPC: 21662306a36Sopenharmony_ci audit_log_format(ab, " ipc_key=%d ", a->u.ipc_id); 21762306a36Sopenharmony_ci break; 21862306a36Sopenharmony_ci case LSM_AUDIT_DATA_CAP: 21962306a36Sopenharmony_ci audit_log_format(ab, " capability=%d ", a->u.cap); 22062306a36Sopenharmony_ci break; 22162306a36Sopenharmony_ci case LSM_AUDIT_DATA_PATH: { 22262306a36Sopenharmony_ci struct inode *inode; 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci audit_log_d_path(ab, " path=", &a->u.path); 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci inode = d_backing_inode(a->u.path.dentry); 22762306a36Sopenharmony_ci if (inode) { 22862306a36Sopenharmony_ci audit_log_format(ab, " dev="); 22962306a36Sopenharmony_ci audit_log_untrustedstring(ab, inode->i_sb->s_id); 23062306a36Sopenharmony_ci audit_log_format(ab, " ino=%lu", inode->i_ino); 23162306a36Sopenharmony_ci } 23262306a36Sopenharmony_ci break; 23362306a36Sopenharmony_ci } 23462306a36Sopenharmony_ci case LSM_AUDIT_DATA_FILE: { 23562306a36Sopenharmony_ci struct inode *inode; 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci audit_log_d_path(ab, " path=", &a->u.file->f_path); 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci inode = file_inode(a->u.file); 24062306a36Sopenharmony_ci if (inode) { 24162306a36Sopenharmony_ci audit_log_format(ab, " dev="); 24262306a36Sopenharmony_ci audit_log_untrustedstring(ab, inode->i_sb->s_id); 24362306a36Sopenharmony_ci audit_log_format(ab, " ino=%lu", inode->i_ino); 24462306a36Sopenharmony_ci } 24562306a36Sopenharmony_ci break; 24662306a36Sopenharmony_ci } 24762306a36Sopenharmony_ci case LSM_AUDIT_DATA_IOCTL_OP: { 24862306a36Sopenharmony_ci struct inode *inode; 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci audit_log_d_path(ab, " path=", &a->u.op->path); 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci inode = a->u.op->path.dentry->d_inode; 25362306a36Sopenharmony_ci if (inode) { 25462306a36Sopenharmony_ci audit_log_format(ab, " dev="); 25562306a36Sopenharmony_ci audit_log_untrustedstring(ab, inode->i_sb->s_id); 25662306a36Sopenharmony_ci audit_log_format(ab, " ino=%lu", inode->i_ino); 25762306a36Sopenharmony_ci } 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci audit_log_format(ab, " ioctlcmd=0x%hx", a->u.op->cmd); 26062306a36Sopenharmony_ci break; 26162306a36Sopenharmony_ci } 26262306a36Sopenharmony_ci case LSM_AUDIT_DATA_DENTRY: { 26362306a36Sopenharmony_ci struct inode *inode; 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci audit_log_format(ab, " name="); 26662306a36Sopenharmony_ci spin_lock(&a->u.dentry->d_lock); 26762306a36Sopenharmony_ci audit_log_untrustedstring(ab, a->u.dentry->d_name.name); 26862306a36Sopenharmony_ci spin_unlock(&a->u.dentry->d_lock); 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci inode = d_backing_inode(a->u.dentry); 27162306a36Sopenharmony_ci if (inode) { 27262306a36Sopenharmony_ci audit_log_format(ab, " dev="); 27362306a36Sopenharmony_ci audit_log_untrustedstring(ab, inode->i_sb->s_id); 27462306a36Sopenharmony_ci audit_log_format(ab, " ino=%lu", inode->i_ino); 27562306a36Sopenharmony_ci } 27662306a36Sopenharmony_ci break; 27762306a36Sopenharmony_ci } 27862306a36Sopenharmony_ci case LSM_AUDIT_DATA_INODE: { 27962306a36Sopenharmony_ci struct dentry *dentry; 28062306a36Sopenharmony_ci struct inode *inode; 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci rcu_read_lock(); 28362306a36Sopenharmony_ci inode = a->u.inode; 28462306a36Sopenharmony_ci dentry = d_find_alias_rcu(inode); 28562306a36Sopenharmony_ci if (dentry) { 28662306a36Sopenharmony_ci audit_log_format(ab, " name="); 28762306a36Sopenharmony_ci spin_lock(&dentry->d_lock); 28862306a36Sopenharmony_ci audit_log_untrustedstring(ab, dentry->d_name.name); 28962306a36Sopenharmony_ci spin_unlock(&dentry->d_lock); 29062306a36Sopenharmony_ci } 29162306a36Sopenharmony_ci audit_log_format(ab, " dev="); 29262306a36Sopenharmony_ci audit_log_untrustedstring(ab, inode->i_sb->s_id); 29362306a36Sopenharmony_ci audit_log_format(ab, " ino=%lu", inode->i_ino); 29462306a36Sopenharmony_ci rcu_read_unlock(); 29562306a36Sopenharmony_ci break; 29662306a36Sopenharmony_ci } 29762306a36Sopenharmony_ci case LSM_AUDIT_DATA_TASK: { 29862306a36Sopenharmony_ci struct task_struct *tsk = a->u.tsk; 29962306a36Sopenharmony_ci if (tsk) { 30062306a36Sopenharmony_ci pid_t pid = task_tgid_nr(tsk); 30162306a36Sopenharmony_ci if (pid) { 30262306a36Sopenharmony_ci char comm[sizeof(tsk->comm)]; 30362306a36Sopenharmony_ci audit_log_format(ab, " opid=%d ocomm=", pid); 30462306a36Sopenharmony_ci audit_log_untrustedstring(ab, 30562306a36Sopenharmony_ci memcpy(comm, tsk->comm, sizeof(comm))); 30662306a36Sopenharmony_ci } 30762306a36Sopenharmony_ci } 30862306a36Sopenharmony_ci break; 30962306a36Sopenharmony_ci } 31062306a36Sopenharmony_ci case LSM_AUDIT_DATA_NET: 31162306a36Sopenharmony_ci if (a->u.net->sk) { 31262306a36Sopenharmony_ci const struct sock *sk = a->u.net->sk; 31362306a36Sopenharmony_ci const struct unix_sock *u; 31462306a36Sopenharmony_ci struct unix_address *addr; 31562306a36Sopenharmony_ci int len = 0; 31662306a36Sopenharmony_ci char *p = NULL; 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ci switch (sk->sk_family) { 31962306a36Sopenharmony_ci case AF_INET: { 32062306a36Sopenharmony_ci const struct inet_sock *inet = inet_sk(sk); 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci print_ipv4_addr(ab, inet->inet_rcv_saddr, 32362306a36Sopenharmony_ci inet->inet_sport, 32462306a36Sopenharmony_ci "laddr", "lport"); 32562306a36Sopenharmony_ci print_ipv4_addr(ab, inet->inet_daddr, 32662306a36Sopenharmony_ci inet->inet_dport, 32762306a36Sopenharmony_ci "faddr", "fport"); 32862306a36Sopenharmony_ci break; 32962306a36Sopenharmony_ci } 33062306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6) 33162306a36Sopenharmony_ci case AF_INET6: { 33262306a36Sopenharmony_ci const struct inet_sock *inet = inet_sk(sk); 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci print_ipv6_addr(ab, &sk->sk_v6_rcv_saddr, 33562306a36Sopenharmony_ci inet->inet_sport, 33662306a36Sopenharmony_ci "laddr", "lport"); 33762306a36Sopenharmony_ci print_ipv6_addr(ab, &sk->sk_v6_daddr, 33862306a36Sopenharmony_ci inet->inet_dport, 33962306a36Sopenharmony_ci "faddr", "fport"); 34062306a36Sopenharmony_ci break; 34162306a36Sopenharmony_ci } 34262306a36Sopenharmony_ci#endif 34362306a36Sopenharmony_ci case AF_UNIX: 34462306a36Sopenharmony_ci u = unix_sk(sk); 34562306a36Sopenharmony_ci addr = smp_load_acquire(&u->addr); 34662306a36Sopenharmony_ci if (!addr) 34762306a36Sopenharmony_ci break; 34862306a36Sopenharmony_ci if (u->path.dentry) { 34962306a36Sopenharmony_ci audit_log_d_path(ab, " path=", &u->path); 35062306a36Sopenharmony_ci break; 35162306a36Sopenharmony_ci } 35262306a36Sopenharmony_ci len = addr->len-sizeof(short); 35362306a36Sopenharmony_ci p = &addr->name->sun_path[0]; 35462306a36Sopenharmony_ci audit_log_format(ab, " path="); 35562306a36Sopenharmony_ci if (*p) 35662306a36Sopenharmony_ci audit_log_untrustedstring(ab, p); 35762306a36Sopenharmony_ci else 35862306a36Sopenharmony_ci audit_log_n_hex(ab, p, len); 35962306a36Sopenharmony_ci break; 36062306a36Sopenharmony_ci } 36162306a36Sopenharmony_ci } 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci switch (a->u.net->family) { 36462306a36Sopenharmony_ci case AF_INET: 36562306a36Sopenharmony_ci print_ipv4_addr(ab, a->u.net->v4info.saddr, 36662306a36Sopenharmony_ci a->u.net->sport, 36762306a36Sopenharmony_ci "saddr", "src"); 36862306a36Sopenharmony_ci print_ipv4_addr(ab, a->u.net->v4info.daddr, 36962306a36Sopenharmony_ci a->u.net->dport, 37062306a36Sopenharmony_ci "daddr", "dest"); 37162306a36Sopenharmony_ci break; 37262306a36Sopenharmony_ci case AF_INET6: 37362306a36Sopenharmony_ci print_ipv6_addr(ab, &a->u.net->v6info.saddr, 37462306a36Sopenharmony_ci a->u.net->sport, 37562306a36Sopenharmony_ci "saddr", "src"); 37662306a36Sopenharmony_ci print_ipv6_addr(ab, &a->u.net->v6info.daddr, 37762306a36Sopenharmony_ci a->u.net->dport, 37862306a36Sopenharmony_ci "daddr", "dest"); 37962306a36Sopenharmony_ci break; 38062306a36Sopenharmony_ci } 38162306a36Sopenharmony_ci if (a->u.net->netif > 0) { 38262306a36Sopenharmony_ci struct net_device *dev; 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_ci /* NOTE: we always use init's namespace */ 38562306a36Sopenharmony_ci dev = dev_get_by_index(&init_net, a->u.net->netif); 38662306a36Sopenharmony_ci if (dev) { 38762306a36Sopenharmony_ci audit_log_format(ab, " netif=%s", dev->name); 38862306a36Sopenharmony_ci dev_put(dev); 38962306a36Sopenharmony_ci } 39062306a36Sopenharmony_ci } 39162306a36Sopenharmony_ci break; 39262306a36Sopenharmony_ci#ifdef CONFIG_KEYS 39362306a36Sopenharmony_ci case LSM_AUDIT_DATA_KEY: 39462306a36Sopenharmony_ci audit_log_format(ab, " key_serial=%u", a->u.key_struct.key); 39562306a36Sopenharmony_ci if (a->u.key_struct.key_desc) { 39662306a36Sopenharmony_ci audit_log_format(ab, " key_desc="); 39762306a36Sopenharmony_ci audit_log_untrustedstring(ab, a->u.key_struct.key_desc); 39862306a36Sopenharmony_ci } 39962306a36Sopenharmony_ci break; 40062306a36Sopenharmony_ci#endif 40162306a36Sopenharmony_ci case LSM_AUDIT_DATA_KMOD: 40262306a36Sopenharmony_ci audit_log_format(ab, " kmod="); 40362306a36Sopenharmony_ci audit_log_untrustedstring(ab, a->u.kmod_name); 40462306a36Sopenharmony_ci break; 40562306a36Sopenharmony_ci case LSM_AUDIT_DATA_IBPKEY: { 40662306a36Sopenharmony_ci struct in6_addr sbn_pfx; 40762306a36Sopenharmony_ci 40862306a36Sopenharmony_ci memset(&sbn_pfx.s6_addr, 0, 40962306a36Sopenharmony_ci sizeof(sbn_pfx.s6_addr)); 41062306a36Sopenharmony_ci memcpy(&sbn_pfx.s6_addr, &a->u.ibpkey->subnet_prefix, 41162306a36Sopenharmony_ci sizeof(a->u.ibpkey->subnet_prefix)); 41262306a36Sopenharmony_ci audit_log_format(ab, " pkey=0x%x subnet_prefix=%pI6c", 41362306a36Sopenharmony_ci a->u.ibpkey->pkey, &sbn_pfx); 41462306a36Sopenharmony_ci break; 41562306a36Sopenharmony_ci } 41662306a36Sopenharmony_ci case LSM_AUDIT_DATA_IBENDPORT: 41762306a36Sopenharmony_ci audit_log_format(ab, " device=%s port_num=%u", 41862306a36Sopenharmony_ci a->u.ibendport->dev_name, 41962306a36Sopenharmony_ci a->u.ibendport->port); 42062306a36Sopenharmony_ci break; 42162306a36Sopenharmony_ci case LSM_AUDIT_DATA_LOCKDOWN: 42262306a36Sopenharmony_ci audit_log_format(ab, " lockdown_reason=\"%s\"", 42362306a36Sopenharmony_ci lockdown_reasons[a->u.reason]); 42462306a36Sopenharmony_ci break; 42562306a36Sopenharmony_ci case LSM_AUDIT_DATA_ANONINODE: 42662306a36Sopenharmony_ci audit_log_format(ab, " anonclass=%s", a->u.anonclass); 42762306a36Sopenharmony_ci break; 42862306a36Sopenharmony_ci } /* switch (a->type) */ 42962306a36Sopenharmony_ci} 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_ci/** 43262306a36Sopenharmony_ci * common_lsm_audit - generic LSM auditing function 43362306a36Sopenharmony_ci * @a: auxiliary audit data 43462306a36Sopenharmony_ci * @pre_audit: lsm-specific pre-audit callback 43562306a36Sopenharmony_ci * @post_audit: lsm-specific post-audit callback 43662306a36Sopenharmony_ci * 43762306a36Sopenharmony_ci * setup the audit buffer for common security information 43862306a36Sopenharmony_ci * uses callback to print LSM specific information 43962306a36Sopenharmony_ci */ 44062306a36Sopenharmony_civoid common_lsm_audit(struct common_audit_data *a, 44162306a36Sopenharmony_ci void (*pre_audit)(struct audit_buffer *, void *), 44262306a36Sopenharmony_ci void (*post_audit)(struct audit_buffer *, void *)) 44362306a36Sopenharmony_ci{ 44462306a36Sopenharmony_ci struct audit_buffer *ab; 44562306a36Sopenharmony_ci 44662306a36Sopenharmony_ci if (a == NULL) 44762306a36Sopenharmony_ci return; 44862306a36Sopenharmony_ci /* we use GFP_ATOMIC so we won't sleep */ 44962306a36Sopenharmony_ci ab = audit_log_start(audit_context(), GFP_ATOMIC | __GFP_NOWARN, 45062306a36Sopenharmony_ci AUDIT_AVC); 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ci if (ab == NULL) 45362306a36Sopenharmony_ci return; 45462306a36Sopenharmony_ci 45562306a36Sopenharmony_ci if (pre_audit) 45662306a36Sopenharmony_ci pre_audit(ab, a); 45762306a36Sopenharmony_ci 45862306a36Sopenharmony_ci dump_common_audit_data(ab, a); 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_ci if (post_audit) 46162306a36Sopenharmony_ci post_audit(ab, a); 46262306a36Sopenharmony_ci 46362306a36Sopenharmony_ci audit_log_end(ab); 46462306a36Sopenharmony_ci} 465