Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * common LSM auditing functions
0004  *
0005  * Based on code written for SELinux by :
0006  *          Stephen Smalley, <sds@tycho.nsa.gov>
0007  *          James Morris <jmorris@redhat.com>
0008  * Author : Etienne Basset, <etienne.basset@ensta.org>
0009  */
0010 
0011 #include <linux/types.h>
0012 #include <linux/stddef.h>
0013 #include <linux/kernel.h>
0014 #include <linux/gfp.h>
0015 #include <linux/fs.h>
0016 #include <linux/init.h>
0017 #include <net/sock.h>
0018 #include <linux/un.h>
0019 #include <net/af_unix.h>
0020 #include <linux/audit.h>
0021 #include <linux/ipv6.h>
0022 #include <linux/ip.h>
0023 #include <net/ip.h>
0024 #include <net/ipv6.h>
0025 #include <linux/tcp.h>
0026 #include <linux/udp.h>
0027 #include <linux/dccp.h>
0028 #include <linux/sctp.h>
0029 #include <linux/lsm_audit.h>
0030 #include <linux/security.h>
0031 
0032 /**
0033  * ipv4_skb_to_auditdata : fill auditdata from skb
0034  * @skb : the skb
0035  * @ad : the audit data to fill
0036  * @proto : the layer 4 protocol
0037  *
0038  * return  0 on success
0039  */
0040 int ipv4_skb_to_auditdata(struct sk_buff *skb,
0041         struct common_audit_data *ad, u8 *proto)
0042 {
0043     int ret = 0;
0044     struct iphdr *ih;
0045 
0046     ih = ip_hdr(skb);
0047     if (ih == NULL)
0048         return -EINVAL;
0049 
0050     ad->u.net->v4info.saddr = ih->saddr;
0051     ad->u.net->v4info.daddr = ih->daddr;
0052 
0053     if (proto)
0054         *proto = ih->protocol;
0055     /* non initial fragment */
0056     if (ntohs(ih->frag_off) & IP_OFFSET)
0057         return 0;
0058 
0059     switch (ih->protocol) {
0060     case IPPROTO_TCP: {
0061         struct tcphdr *th = tcp_hdr(skb);
0062         if (th == NULL)
0063             break;
0064 
0065         ad->u.net->sport = th->source;
0066         ad->u.net->dport = th->dest;
0067         break;
0068     }
0069     case IPPROTO_UDP: {
0070         struct udphdr *uh = udp_hdr(skb);
0071         if (uh == NULL)
0072             break;
0073 
0074         ad->u.net->sport = uh->source;
0075         ad->u.net->dport = uh->dest;
0076         break;
0077     }
0078     case IPPROTO_DCCP: {
0079         struct dccp_hdr *dh = dccp_hdr(skb);
0080         if (dh == NULL)
0081             break;
0082 
0083         ad->u.net->sport = dh->dccph_sport;
0084         ad->u.net->dport = dh->dccph_dport;
0085         break;
0086     }
0087     case IPPROTO_SCTP: {
0088         struct sctphdr *sh = sctp_hdr(skb);
0089         if (sh == NULL)
0090             break;
0091         ad->u.net->sport = sh->source;
0092         ad->u.net->dport = sh->dest;
0093         break;
0094     }
0095     default:
0096         ret = -EINVAL;
0097     }
0098     return ret;
0099 }
0100 #if IS_ENABLED(CONFIG_IPV6)
0101 /**
0102  * ipv6_skb_to_auditdata : fill auditdata from skb
0103  * @skb : the skb
0104  * @ad : the audit data to fill
0105  * @proto : the layer 4 protocol
0106  *
0107  * return  0 on success
0108  */
0109 int ipv6_skb_to_auditdata(struct sk_buff *skb,
0110         struct common_audit_data *ad, u8 *proto)
0111 {
0112     int offset, ret = 0;
0113     struct ipv6hdr *ip6;
0114     u8 nexthdr;
0115     __be16 frag_off;
0116 
0117     ip6 = ipv6_hdr(skb);
0118     if (ip6 == NULL)
0119         return -EINVAL;
0120     ad->u.net->v6info.saddr = ip6->saddr;
0121     ad->u.net->v6info.daddr = ip6->daddr;
0122     /* IPv6 can have several extension header before the Transport header
0123      * skip them */
0124     offset = skb_network_offset(skb);
0125     offset += sizeof(*ip6);
0126     nexthdr = ip6->nexthdr;
0127     offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off);
0128     if (offset < 0)
0129         return 0;
0130     if (proto)
0131         *proto = nexthdr;
0132     switch (nexthdr) {
0133     case IPPROTO_TCP: {
0134         struct tcphdr _tcph, *th;
0135 
0136         th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
0137         if (th == NULL)
0138             break;
0139 
0140         ad->u.net->sport = th->source;
0141         ad->u.net->dport = th->dest;
0142         break;
0143     }
0144     case IPPROTO_UDP: {
0145         struct udphdr _udph, *uh;
0146 
0147         uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
0148         if (uh == NULL)
0149             break;
0150 
0151         ad->u.net->sport = uh->source;
0152         ad->u.net->dport = uh->dest;
0153         break;
0154     }
0155     case IPPROTO_DCCP: {
0156         struct dccp_hdr _dccph, *dh;
0157 
0158         dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
0159         if (dh == NULL)
0160             break;
0161 
0162         ad->u.net->sport = dh->dccph_sport;
0163         ad->u.net->dport = dh->dccph_dport;
0164         break;
0165     }
0166     case IPPROTO_SCTP: {
0167         struct sctphdr _sctph, *sh;
0168 
0169         sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph);
0170         if (sh == NULL)
0171             break;
0172         ad->u.net->sport = sh->source;
0173         ad->u.net->dport = sh->dest;
0174         break;
0175     }
0176     default:
0177         ret = -EINVAL;
0178     }
0179     return ret;
0180 }
0181 #endif
0182 
0183 
0184 static inline void print_ipv6_addr(struct audit_buffer *ab,
0185                    const struct in6_addr *addr, __be16 port,
0186                    char *name1, char *name2)
0187 {
0188     if (!ipv6_addr_any(addr))
0189         audit_log_format(ab, " %s=%pI6c", name1, addr);
0190     if (port)
0191         audit_log_format(ab, " %s=%d", name2, ntohs(port));
0192 }
0193 
0194 static inline void print_ipv4_addr(struct audit_buffer *ab, __be32 addr,
0195                    __be16 port, char *name1, char *name2)
0196 {
0197     if (addr)
0198         audit_log_format(ab, " %s=%pI4", name1, &addr);
0199     if (port)
0200         audit_log_format(ab, " %s=%d", name2, ntohs(port));
0201 }
0202 
0203 /**
0204  * dump_common_audit_data - helper to dump common audit data
0205  * @a : common audit data
0206  *
0207  */
0208 static void dump_common_audit_data(struct audit_buffer *ab,
0209                    struct common_audit_data *a)
0210 {
0211     char comm[sizeof(current->comm)];
0212 
0213     /*
0214      * To keep stack sizes in check force programers to notice if they
0215      * start making this union too large!  See struct lsm_network_audit
0216      * as an example of how to deal with large data.
0217      */
0218     BUILD_BUG_ON(sizeof(a->u) > sizeof(void *)*2);
0219 
0220     audit_log_format(ab, " pid=%d comm=", task_tgid_nr(current));
0221     audit_log_untrustedstring(ab, memcpy(comm, current->comm, sizeof(comm)));
0222 
0223     switch (a->type) {
0224     case LSM_AUDIT_DATA_NONE:
0225         return;
0226     case LSM_AUDIT_DATA_IPC:
0227         audit_log_format(ab, " ipc_key=%d ", a->u.ipc_id);
0228         break;
0229     case LSM_AUDIT_DATA_CAP:
0230         audit_log_format(ab, " capability=%d ", a->u.cap);
0231         break;
0232     case LSM_AUDIT_DATA_PATH: {
0233         struct inode *inode;
0234 
0235         audit_log_d_path(ab, " path=", &a->u.path);
0236 
0237         inode = d_backing_inode(a->u.path.dentry);
0238         if (inode) {
0239             audit_log_format(ab, " dev=");
0240             audit_log_untrustedstring(ab, inode->i_sb->s_id);
0241             audit_log_format(ab, " ino=%lu", inode->i_ino);
0242         }
0243         break;
0244     }
0245     case LSM_AUDIT_DATA_FILE: {
0246         struct inode *inode;
0247 
0248         audit_log_d_path(ab, " path=", &a->u.file->f_path);
0249 
0250         inode = file_inode(a->u.file);
0251         if (inode) {
0252             audit_log_format(ab, " dev=");
0253             audit_log_untrustedstring(ab, inode->i_sb->s_id);
0254             audit_log_format(ab, " ino=%lu", inode->i_ino);
0255         }
0256         break;
0257     }
0258     case LSM_AUDIT_DATA_IOCTL_OP: {
0259         struct inode *inode;
0260 
0261         audit_log_d_path(ab, " path=", &a->u.op->path);
0262 
0263         inode = a->u.op->path.dentry->d_inode;
0264         if (inode) {
0265             audit_log_format(ab, " dev=");
0266             audit_log_untrustedstring(ab, inode->i_sb->s_id);
0267             audit_log_format(ab, " ino=%lu", inode->i_ino);
0268         }
0269 
0270         audit_log_format(ab, " ioctlcmd=0x%hx", a->u.op->cmd);
0271         break;
0272     }
0273     case LSM_AUDIT_DATA_DENTRY: {
0274         struct inode *inode;
0275 
0276         audit_log_format(ab, " name=");
0277         spin_lock(&a->u.dentry->d_lock);
0278         audit_log_untrustedstring(ab, a->u.dentry->d_name.name);
0279         spin_unlock(&a->u.dentry->d_lock);
0280 
0281         inode = d_backing_inode(a->u.dentry);
0282         if (inode) {
0283             audit_log_format(ab, " dev=");
0284             audit_log_untrustedstring(ab, inode->i_sb->s_id);
0285             audit_log_format(ab, " ino=%lu", inode->i_ino);
0286         }
0287         break;
0288     }
0289     case LSM_AUDIT_DATA_INODE: {
0290         struct dentry *dentry;
0291         struct inode *inode;
0292 
0293         rcu_read_lock();
0294         inode = a->u.inode;
0295         dentry = d_find_alias_rcu(inode);
0296         if (dentry) {
0297             audit_log_format(ab, " name=");
0298             spin_lock(&dentry->d_lock);
0299             audit_log_untrustedstring(ab, dentry->d_name.name);
0300             spin_unlock(&dentry->d_lock);
0301         }
0302         audit_log_format(ab, " dev=");
0303         audit_log_untrustedstring(ab, inode->i_sb->s_id);
0304         audit_log_format(ab, " ino=%lu", inode->i_ino);
0305         rcu_read_unlock();
0306         break;
0307     }
0308     case LSM_AUDIT_DATA_TASK: {
0309         struct task_struct *tsk = a->u.tsk;
0310         if (tsk) {
0311             pid_t pid = task_tgid_nr(tsk);
0312             if (pid) {
0313                 char comm[sizeof(tsk->comm)];
0314                 audit_log_format(ab, " opid=%d ocomm=", pid);
0315                 audit_log_untrustedstring(ab,
0316                     memcpy(comm, tsk->comm, sizeof(comm)));
0317             }
0318         }
0319         break;
0320     }
0321     case LSM_AUDIT_DATA_NET:
0322         if (a->u.net->sk) {
0323             const struct sock *sk = a->u.net->sk;
0324             struct unix_sock *u;
0325             struct unix_address *addr;
0326             int len = 0;
0327             char *p = NULL;
0328 
0329             switch (sk->sk_family) {
0330             case AF_INET: {
0331                 struct inet_sock *inet = inet_sk(sk);
0332 
0333                 print_ipv4_addr(ab, inet->inet_rcv_saddr,
0334                         inet->inet_sport,
0335                         "laddr", "lport");
0336                 print_ipv4_addr(ab, inet->inet_daddr,
0337                         inet->inet_dport,
0338                         "faddr", "fport");
0339                 break;
0340             }
0341 #if IS_ENABLED(CONFIG_IPV6)
0342             case AF_INET6: {
0343                 struct inet_sock *inet = inet_sk(sk);
0344 
0345                 print_ipv6_addr(ab, &sk->sk_v6_rcv_saddr,
0346                         inet->inet_sport,
0347                         "laddr", "lport");
0348                 print_ipv6_addr(ab, &sk->sk_v6_daddr,
0349                         inet->inet_dport,
0350                         "faddr", "fport");
0351                 break;
0352             }
0353 #endif
0354             case AF_UNIX:
0355                 u = unix_sk(sk);
0356                 addr = smp_load_acquire(&u->addr);
0357                 if (!addr)
0358                     break;
0359                 if (u->path.dentry) {
0360                     audit_log_d_path(ab, " path=", &u->path);
0361                     break;
0362                 }
0363                 len = addr->len-sizeof(short);
0364                 p = &addr->name->sun_path[0];
0365                 audit_log_format(ab, " path=");
0366                 if (*p)
0367                     audit_log_untrustedstring(ab, p);
0368                 else
0369                     audit_log_n_hex(ab, p, len);
0370                 break;
0371             }
0372         }
0373 
0374         switch (a->u.net->family) {
0375         case AF_INET:
0376             print_ipv4_addr(ab, a->u.net->v4info.saddr,
0377                     a->u.net->sport,
0378                     "saddr", "src");
0379             print_ipv4_addr(ab, a->u.net->v4info.daddr,
0380                     a->u.net->dport,
0381                     "daddr", "dest");
0382             break;
0383         case AF_INET6:
0384             print_ipv6_addr(ab, &a->u.net->v6info.saddr,
0385                     a->u.net->sport,
0386                     "saddr", "src");
0387             print_ipv6_addr(ab, &a->u.net->v6info.daddr,
0388                     a->u.net->dport,
0389                     "daddr", "dest");
0390             break;
0391         }
0392         if (a->u.net->netif > 0) {
0393             struct net_device *dev;
0394 
0395             /* NOTE: we always use init's namespace */
0396             dev = dev_get_by_index(&init_net, a->u.net->netif);
0397             if (dev) {
0398                 audit_log_format(ab, " netif=%s", dev->name);
0399                 dev_put(dev);
0400             }
0401         }
0402         break;
0403 #ifdef CONFIG_KEYS
0404     case LSM_AUDIT_DATA_KEY:
0405         audit_log_format(ab, " key_serial=%u", a->u.key_struct.key);
0406         if (a->u.key_struct.key_desc) {
0407             audit_log_format(ab, " key_desc=");
0408             audit_log_untrustedstring(ab, a->u.key_struct.key_desc);
0409         }
0410         break;
0411 #endif
0412     case LSM_AUDIT_DATA_KMOD:
0413         audit_log_format(ab, " kmod=");
0414         audit_log_untrustedstring(ab, a->u.kmod_name);
0415         break;
0416     case LSM_AUDIT_DATA_IBPKEY: {
0417         struct in6_addr sbn_pfx;
0418 
0419         memset(&sbn_pfx.s6_addr, 0,
0420                sizeof(sbn_pfx.s6_addr));
0421         memcpy(&sbn_pfx.s6_addr, &a->u.ibpkey->subnet_prefix,
0422                sizeof(a->u.ibpkey->subnet_prefix));
0423         audit_log_format(ab, " pkey=0x%x subnet_prefix=%pI6c",
0424                  a->u.ibpkey->pkey, &sbn_pfx);
0425         break;
0426     }
0427     case LSM_AUDIT_DATA_IBENDPORT:
0428         audit_log_format(ab, " device=%s port_num=%u",
0429                  a->u.ibendport->dev_name,
0430                  a->u.ibendport->port);
0431         break;
0432     case LSM_AUDIT_DATA_LOCKDOWN:
0433         audit_log_format(ab, " lockdown_reason=\"%s\"",
0434                  lockdown_reasons[a->u.reason]);
0435         break;
0436     case LSM_AUDIT_DATA_ANONINODE:
0437         audit_log_format(ab, " anonclass=%s", a->u.anonclass);
0438         break;
0439     } /* switch (a->type) */
0440 }
0441 
0442 /**
0443  * common_lsm_audit - generic LSM auditing function
0444  * @a:  auxiliary audit data
0445  * @pre_audit: lsm-specific pre-audit callback
0446  * @post_audit: lsm-specific post-audit callback
0447  *
0448  * setup the audit buffer for common security information
0449  * uses callback to print LSM specific information
0450  */
0451 void common_lsm_audit(struct common_audit_data *a,
0452     void (*pre_audit)(struct audit_buffer *, void *),
0453     void (*post_audit)(struct audit_buffer *, void *))
0454 {
0455     struct audit_buffer *ab;
0456 
0457     if (a == NULL)
0458         return;
0459     /* we use GFP_ATOMIC so we won't sleep */
0460     ab = audit_log_start(audit_context(), GFP_ATOMIC | __GFP_NOWARN,
0461                  AUDIT_AVC);
0462 
0463     if (ab == NULL)
0464         return;
0465 
0466     if (pre_audit)
0467         pre_audit(ab, a);
0468 
0469     dump_common_audit_data(ab, a);
0470 
0471     if (post_audit)
0472         post_audit(ab, a);
0473 
0474     audit_log_end(ab);
0475 }