Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
lsm_audit.c
Go to the documentation of this file.
1 /*
2  * common LSM auditing functions
3  *
4  * Based on code written for SELinux by :
5  * Stephen Smalley, <[email protected]>
6  * James Morris <[email protected]>
7  * Author : Etienne Basset, <[email protected]>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2,
11  * as published by the Free Software Foundation.
12  */
13 
14 #include <linux/types.h>
15 #include <linux/stddef.h>
16 #include <linux/kernel.h>
17 #include <linux/gfp.h>
18 #include <linux/fs.h>
19 #include <linux/init.h>
20 #include <net/sock.h>
21 #include <linux/un.h>
22 #include <net/af_unix.h>
23 #include <linux/audit.h>
24 #include <linux/ipv6.h>
25 #include <linux/ip.h>
26 #include <net/ip.h>
27 #include <net/ipv6.h>
28 #include <linux/tcp.h>
29 #include <linux/udp.h>
30 #include <linux/dccp.h>
31 #include <linux/sctp.h>
32 #include <linux/lsm_audit.h>
33 
43  struct common_audit_data *ad, u8 *proto)
44 {
45  int ret = 0;
46  struct iphdr *ih;
47 
48  ih = ip_hdr(skb);
49  if (ih == NULL)
50  return -EINVAL;
51 
52  ad->u.net->v4info.saddr = ih->saddr;
53  ad->u.net->v4info.daddr = ih->daddr;
54 
55  if (proto)
56  *proto = ih->protocol;
57  /* non initial fragment */
58  if (ntohs(ih->frag_off) & IP_OFFSET)
59  return 0;
60 
61  switch (ih->protocol) {
62  case IPPROTO_TCP: {
63  struct tcphdr *th = tcp_hdr(skb);
64  if (th == NULL)
65  break;
66 
67  ad->u.net->sport = th->source;
68  ad->u.net->dport = th->dest;
69  break;
70  }
71  case IPPROTO_UDP: {
72  struct udphdr *uh = udp_hdr(skb);
73  if (uh == NULL)
74  break;
75 
76  ad->u.net->sport = uh->source;
77  ad->u.net->dport = uh->dest;
78  break;
79  }
80  case IPPROTO_DCCP: {
81  struct dccp_hdr *dh = dccp_hdr(skb);
82  if (dh == NULL)
83  break;
84 
85  ad->u.net->sport = dh->dccph_sport;
86  ad->u.net->dport = dh->dccph_dport;
87  break;
88  }
89  case IPPROTO_SCTP: {
90  struct sctphdr *sh = sctp_hdr(skb);
91  if (sh == NULL)
92  break;
93  ad->u.net->sport = sh->source;
94  ad->u.net->dport = sh->dest;
95  break;
96  }
97  default:
98  ret = -EINVAL;
99  }
100  return ret;
101 }
102 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
103 
111 int ipv6_skb_to_auditdata(struct sk_buff *skb,
112  struct common_audit_data *ad, u8 *proto)
113 {
114  int offset, ret = 0;
115  struct ipv6hdr *ip6;
116  u8 nexthdr;
117  __be16 frag_off;
118 
119  ip6 = ipv6_hdr(skb);
120  if (ip6 == NULL)
121  return -EINVAL;
122  ad->u.net->v6info.saddr = ip6->saddr;
123  ad->u.net->v6info.daddr = ip6->daddr;
124  ret = 0;
125  /* IPv6 can have several extension header before the Transport header
126  * skip them */
127  offset = skb_network_offset(skb);
128  offset += sizeof(*ip6);
129  nexthdr = ip6->nexthdr;
130  offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off);
131  if (offset < 0)
132  return 0;
133  if (proto)
134  *proto = nexthdr;
135  switch (nexthdr) {
136  case IPPROTO_TCP: {
137  struct tcphdr _tcph, *th;
138 
139  th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
140  if (th == NULL)
141  break;
142 
143  ad->u.net->sport = th->source;
144  ad->u.net->dport = th->dest;
145  break;
146  }
147  case IPPROTO_UDP: {
148  struct udphdr _udph, *uh;
149 
150  uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
151  if (uh == NULL)
152  break;
153 
154  ad->u.net->sport = uh->source;
155  ad->u.net->dport = uh->dest;
156  break;
157  }
158  case IPPROTO_DCCP: {
159  struct dccp_hdr _dccph, *dh;
160 
161  dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
162  if (dh == NULL)
163  break;
164 
165  ad->u.net->sport = dh->dccph_sport;
166  ad->u.net->dport = dh->dccph_dport;
167  break;
168  }
169  case IPPROTO_SCTP: {
170  struct sctphdr _sctph, *sh;
171 
172  sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph);
173  if (sh == NULL)
174  break;
175  ad->u.net->sport = sh->source;
176  ad->u.net->dport = sh->dest;
177  break;
178  }
179  default:
180  ret = -EINVAL;
181  }
182  return ret;
183 }
184 #endif
185 
186 
187 static inline void print_ipv6_addr(struct audit_buffer *ab,
188  struct in6_addr *addr, __be16 port,
189  char *name1, char *name2)
190 {
191  if (!ipv6_addr_any(addr))
192  audit_log_format(ab, " %s=%pI6c", name1, addr);
193  if (port)
194  audit_log_format(ab, " %s=%d", name2, ntohs(port));
195 }
196 
197 static inline void print_ipv4_addr(struct audit_buffer *ab, __be32 addr,
198  __be16 port, char *name1, char *name2)
199 {
200  if (addr)
201  audit_log_format(ab, " %s=%pI4", name1, &addr);
202  if (port)
203  audit_log_format(ab, " %s=%d", name2, ntohs(port));
204 }
205 
211 static void dump_common_audit_data(struct audit_buffer *ab,
212  struct common_audit_data *a)
213 {
214  struct task_struct *tsk = current;
215 
216  /*
217  * To keep stack sizes in check force programers to notice if they
218  * start making this union too large! See struct lsm_network_audit
219  * as an example of how to deal with large data.
220  */
221  BUILD_BUG_ON(sizeof(a->u) > sizeof(void *)*2);
222 
223  audit_log_format(ab, " pid=%d comm=", tsk->pid);
225 
226  switch (a->type) {
227  case LSM_AUDIT_DATA_NONE:
228  return;
229  case LSM_AUDIT_DATA_IPC:
230  audit_log_format(ab, " key=%d ", a->u.ipc_id);
231  break;
232  case LSM_AUDIT_DATA_CAP:
233  audit_log_format(ab, " capability=%d ", a->u.cap);
234  break;
235  case LSM_AUDIT_DATA_PATH: {
236  struct inode *inode;
237 
238  audit_log_d_path(ab, " path=", &a->u.path);
239 
240  inode = a->u.path.dentry->d_inode;
241  if (inode) {
242  audit_log_format(ab, " dev=");
243  audit_log_untrustedstring(ab, inode->i_sb->s_id);
244  audit_log_format(ab, " ino=%lu", inode->i_ino);
245  }
246  break;
247  }
248  case LSM_AUDIT_DATA_DENTRY: {
249  struct inode *inode;
250 
251  audit_log_format(ab, " name=");
252  audit_log_untrustedstring(ab, a->u.dentry->d_name.name);
253 
254  inode = a->u.dentry->d_inode;
255  if (inode) {
256  audit_log_format(ab, " dev=");
257  audit_log_untrustedstring(ab, inode->i_sb->s_id);
258  audit_log_format(ab, " ino=%lu", inode->i_ino);
259  }
260  break;
261  }
262  case LSM_AUDIT_DATA_INODE: {
263  struct dentry *dentry;
264  struct inode *inode;
265 
266  inode = a->u.inode;
267  dentry = d_find_alias(inode);
268  if (dentry) {
269  audit_log_format(ab, " name=");
271  dentry->d_name.name);
272  dput(dentry);
273  }
274  audit_log_format(ab, " dev=");
275  audit_log_untrustedstring(ab, inode->i_sb->s_id);
276  audit_log_format(ab, " ino=%lu", inode->i_ino);
277  break;
278  }
279  case LSM_AUDIT_DATA_TASK:
280  tsk = a->u.tsk;
281  if (tsk && tsk->pid) {
282  audit_log_format(ab, " pid=%d comm=", tsk->pid);
284  }
285  break;
286  case LSM_AUDIT_DATA_NET:
287  if (a->u.net->sk) {
288  struct sock *sk = a->u.net->sk;
289  struct unix_sock *u;
290  int len = 0;
291  char *p = NULL;
292 
293  switch (sk->sk_family) {
294  case AF_INET: {
295  struct inet_sock *inet = inet_sk(sk);
296 
297  print_ipv4_addr(ab, inet->inet_rcv_saddr,
298  inet->inet_sport,
299  "laddr", "lport");
300  print_ipv4_addr(ab, inet->inet_daddr,
301  inet->inet_dport,
302  "faddr", "fport");
303  break;
304  }
305  case AF_INET6: {
306  struct inet_sock *inet = inet_sk(sk);
307  struct ipv6_pinfo *inet6 = inet6_sk(sk);
308 
309  print_ipv6_addr(ab, &inet6->rcv_saddr,
310  inet->inet_sport,
311  "laddr", "lport");
312  print_ipv6_addr(ab, &inet6->daddr,
313  inet->inet_dport,
314  "faddr", "fport");
315  break;
316  }
317  case AF_UNIX:
318  u = unix_sk(sk);
319  if (u->path.dentry) {
320  audit_log_d_path(ab, " path=", &u->path);
321  break;
322  }
323  if (!u->addr)
324  break;
325  len = u->addr->len-sizeof(short);
326  p = &u->addr->name->sun_path[0];
327  audit_log_format(ab, " path=");
328  if (*p)
330  else
331  audit_log_n_hex(ab, p, len);
332  break;
333  }
334  }
335 
336  switch (a->u.net->family) {
337  case AF_INET:
338  print_ipv4_addr(ab, a->u.net->v4info.saddr,
339  a->u.net->sport,
340  "saddr", "src");
341  print_ipv4_addr(ab, a->u.net->v4info.daddr,
342  a->u.net->dport,
343  "daddr", "dest");
344  break;
345  case AF_INET6:
346  print_ipv6_addr(ab, &a->u.net->v6info.saddr,
347  a->u.net->sport,
348  "saddr", "src");
349  print_ipv6_addr(ab, &a->u.net->v6info.daddr,
350  a->u.net->dport,
351  "daddr", "dest");
352  break;
353  }
354  if (a->u.net->netif > 0) {
355  struct net_device *dev;
356 
357  /* NOTE: we always use init's namespace */
358  dev = dev_get_by_index(&init_net, a->u.net->netif);
359  if (dev) {
360  audit_log_format(ab, " netif=%s", dev->name);
361  dev_put(dev);
362  }
363  }
364  break;
365 #ifdef CONFIG_KEYS
366  case LSM_AUDIT_DATA_KEY:
367  audit_log_format(ab, " key_serial=%u", a->u.key_struct.key);
368  if (a->u.key_struct.key_desc) {
369  audit_log_format(ab, " key_desc=");
370  audit_log_untrustedstring(ab, a->u.key_struct.key_desc);
371  }
372  break;
373 #endif
374  case LSM_AUDIT_DATA_KMOD:
375  audit_log_format(ab, " kmod=");
377  break;
378  } /* switch (a->type) */
379 }
380 
391  void (*pre_audit)(struct audit_buffer *, void *),
392  void (*post_audit)(struct audit_buffer *, void *))
393 {
394  struct audit_buffer *ab;
395 
396  if (a == NULL)
397  return;
398  /* we use GFP_ATOMIC so we won't sleep */
399  ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_AVC);
400 
401  if (ab == NULL)
402  return;
403 
404  if (pre_audit)
405  pre_audit(ab, a);
406 
407  dump_common_audit_data(ab, a);
408 
409  if (post_audit)
410  post_audit(ab, a);
411 
412  audit_log_end(ab);
413 }