GNU Linux-libre 4.9.337-gnu1
[releases.git] / net / ipv6 / netfilter / ip6_tables.c
1 /*
2  * Packet matching code.
3  *
4  * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
5  * Copyright (C) 2000-2005 Netfilter Core Team <coreteam@netfilter.org>
6  * Copyright (c) 2006-2010 Patrick McHardy <kaber@trash.net>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12
13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14
15 #include <linux/kernel.h>
16 #include <linux/capability.h>
17 #include <linux/in.h>
18 #include <linux/skbuff.h>
19 #include <linux/kmod.h>
20 #include <linux/vmalloc.h>
21 #include <linux/netdevice.h>
22 #include <linux/module.h>
23 #include <linux/poison.h>
24 #include <linux/icmpv6.h>
25 #include <net/ipv6.h>
26 #include <net/compat.h>
27 #include <asm/uaccess.h>
28 #include <linux/mutex.h>
29 #include <linux/proc_fs.h>
30 #include <linux/err.h>
31 #include <linux/cpumask.h>
32
33 #include <linux/netfilter_ipv6/ip6_tables.h>
34 #include <linux/netfilter/x_tables.h>
35 #include <net/netfilter/nf_log.h>
36 #include "../../netfilter/xt_repldata.h"
37
38 MODULE_LICENSE("GPL");
39 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
40 MODULE_DESCRIPTION("IPv6 packet filter");
41
42 #ifdef CONFIG_NETFILTER_DEBUG
43 #define IP_NF_ASSERT(x) WARN_ON(!(x))
44 #else
45 #define IP_NF_ASSERT(x)
46 #endif
47
48 void *ip6t_alloc_initial_table(const struct xt_table *info)
49 {
50         return xt_alloc_initial_table(ip6t, IP6T);
51 }
52 EXPORT_SYMBOL_GPL(ip6t_alloc_initial_table);
53
54 /*
55    We keep a set of rules for each CPU, so we can avoid write-locking
56    them in the softirq when updating the counters and therefore
57    only need to read-lock in the softirq; doing a write_lock_bh() in user
58    context stops packets coming through and allows user context to read
59    the counters or update the rules.
60
61    Hence the start of any table is given by get_table() below.  */
62
63 /* Returns whether matches rule or not. */
64 /* Performance critical - called for every packet */
65 static inline bool
66 ip6_packet_match(const struct sk_buff *skb,
67                  const char *indev,
68                  const char *outdev,
69                  const struct ip6t_ip6 *ip6info,
70                  unsigned int *protoff,
71                  int *fragoff, bool *hotdrop)
72 {
73         unsigned long ret;
74         const struct ipv6hdr *ipv6 = ipv6_hdr(skb);
75
76         if (NF_INVF(ip6info, IP6T_INV_SRCIP,
77                     ipv6_masked_addr_cmp(&ipv6->saddr, &ip6info->smsk,
78                                          &ip6info->src)) ||
79             NF_INVF(ip6info, IP6T_INV_DSTIP,
80                     ipv6_masked_addr_cmp(&ipv6->daddr, &ip6info->dmsk,
81                                          &ip6info->dst)))
82                 return false;
83
84         ret = ifname_compare_aligned(indev, ip6info->iniface, ip6info->iniface_mask);
85
86         if (NF_INVF(ip6info, IP6T_INV_VIA_IN, ret != 0))
87                 return false;
88
89         ret = ifname_compare_aligned(outdev, ip6info->outiface, ip6info->outiface_mask);
90
91         if (NF_INVF(ip6info, IP6T_INV_VIA_OUT, ret != 0))
92                 return false;
93
94 /* ... might want to do something with class and flowlabel here ... */
95
96         /* look for the desired protocol header */
97         if (ip6info->flags & IP6T_F_PROTO) {
98                 int protohdr;
99                 unsigned short _frag_off;
100
101                 protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off, NULL);
102                 if (protohdr < 0) {
103                         if (_frag_off == 0)
104                                 *hotdrop = true;
105                         return false;
106                 }
107                 *fragoff = _frag_off;
108
109                 if (ip6info->proto == protohdr) {
110                         if (ip6info->invflags & IP6T_INV_PROTO)
111                                 return false;
112
113                         return true;
114                 }
115
116                 /* We need match for the '-p all', too! */
117                 if ((ip6info->proto != 0) &&
118                         !(ip6info->invflags & IP6T_INV_PROTO))
119                         return false;
120         }
121         return true;
122 }
123
124 /* should be ip6 safe */
125 static bool
126 ip6_checkentry(const struct ip6t_ip6 *ipv6)
127 {
128         if (ipv6->flags & ~IP6T_F_MASK)
129                 return false;
130         if (ipv6->invflags & ~IP6T_INV_MASK)
131                 return false;
132
133         return true;
134 }
135
136 static unsigned int
137 ip6t_error(struct sk_buff *skb, const struct xt_action_param *par)
138 {
139         net_info_ratelimited("error: `%s'\n", (const char *)par->targinfo);
140
141         return NF_DROP;
142 }
143
144 static inline struct ip6t_entry *
145 get_entry(const void *base, unsigned int offset)
146 {
147         return (struct ip6t_entry *)(base + offset);
148 }
149
150 /* All zeroes == unconditional rule. */
151 /* Mildly perf critical (only if packet tracing is on) */
152 static inline bool unconditional(const struct ip6t_entry *e)
153 {
154         static const struct ip6t_ip6 uncond;
155
156         return e->target_offset == sizeof(struct ip6t_entry) &&
157                memcmp(&e->ipv6, &uncond, sizeof(uncond)) == 0;
158 }
159
160 static inline const struct xt_entry_target *
161 ip6t_get_target_c(const struct ip6t_entry *e)
162 {
163         return ip6t_get_target((struct ip6t_entry *)e);
164 }
165
166 #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE)
167 /* This cries for unification! */
168 static const char *const hooknames[] = {
169         [NF_INET_PRE_ROUTING]           = "PREROUTING",
170         [NF_INET_LOCAL_IN]              = "INPUT",
171         [NF_INET_FORWARD]               = "FORWARD",
172         [NF_INET_LOCAL_OUT]             = "OUTPUT",
173         [NF_INET_POST_ROUTING]          = "POSTROUTING",
174 };
175
176 enum nf_ip_trace_comments {
177         NF_IP6_TRACE_COMMENT_RULE,
178         NF_IP6_TRACE_COMMENT_RETURN,
179         NF_IP6_TRACE_COMMENT_POLICY,
180 };
181
182 static const char *const comments[] = {
183         [NF_IP6_TRACE_COMMENT_RULE]     = "rule",
184         [NF_IP6_TRACE_COMMENT_RETURN]   = "return",
185         [NF_IP6_TRACE_COMMENT_POLICY]   = "policy",
186 };
187
188 static struct nf_loginfo trace_loginfo = {
189         .type = NF_LOG_TYPE_LOG,
190         .u = {
191                 .log = {
192                         .level = LOGLEVEL_WARNING,
193                         .logflags = NF_LOG_DEFAULT_MASK,
194                 },
195         },
196 };
197
198 /* Mildly perf critical (only if packet tracing is on) */
199 static inline int
200 get_chainname_rulenum(const struct ip6t_entry *s, const struct ip6t_entry *e,
201                       const char *hookname, const char **chainname,
202                       const char **comment, unsigned int *rulenum)
203 {
204         const struct xt_standard_target *t = (void *)ip6t_get_target_c(s);
205
206         if (strcmp(t->target.u.kernel.target->name, XT_ERROR_TARGET) == 0) {
207                 /* Head of user chain: ERROR target with chainname */
208                 *chainname = t->target.data;
209                 (*rulenum) = 0;
210         } else if (s == e) {
211                 (*rulenum)++;
212
213                 if (unconditional(s) &&
214                     strcmp(t->target.u.kernel.target->name,
215                            XT_STANDARD_TARGET) == 0 &&
216                     t->verdict < 0) {
217                         /* Tail of chains: STANDARD target (return/policy) */
218                         *comment = *chainname == hookname
219                                 ? comments[NF_IP6_TRACE_COMMENT_POLICY]
220                                 : comments[NF_IP6_TRACE_COMMENT_RETURN];
221                 }
222                 return 1;
223         } else
224                 (*rulenum)++;
225
226         return 0;
227 }
228
229 static void trace_packet(struct net *net,
230                          const struct sk_buff *skb,
231                          unsigned int hook,
232                          const struct net_device *in,
233                          const struct net_device *out,
234                          const char *tablename,
235                          const struct xt_table_info *private,
236                          const struct ip6t_entry *e)
237 {
238         const struct ip6t_entry *root;
239         const char *hookname, *chainname, *comment;
240         const struct ip6t_entry *iter;
241         unsigned int rulenum = 0;
242
243         root = get_entry(private->entries, private->hook_entry[hook]);
244
245         hookname = chainname = hooknames[hook];
246         comment = comments[NF_IP6_TRACE_COMMENT_RULE];
247
248         xt_entry_foreach(iter, root, private->size - private->hook_entry[hook])
249                 if (get_chainname_rulenum(iter, e, hookname,
250                     &chainname, &comment, &rulenum) != 0)
251                         break;
252
253         nf_log_trace(net, AF_INET6, hook, skb, in, out, &trace_loginfo,
254                      "TRACE: %s:%s:%s:%u ",
255                      tablename, chainname, comment, rulenum);
256 }
257 #endif
258
259 static inline struct ip6t_entry *
260 ip6t_next_entry(const struct ip6t_entry *entry)
261 {
262         return (void *)entry + entry->next_offset;
263 }
264
265 /* Returns one of the generic firewall policies, like NF_ACCEPT. */
266 unsigned int
267 ip6t_do_table(struct sk_buff *skb,
268               const struct nf_hook_state *state,
269               struct xt_table *table)
270 {
271         unsigned int hook = state->hook;
272         static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
273         /* Initializing verdict to NF_DROP keeps gcc happy. */
274         unsigned int verdict = NF_DROP;
275         const char *indev, *outdev;
276         const void *table_base;
277         struct ip6t_entry *e, **jumpstack;
278         unsigned int stackidx, cpu;
279         const struct xt_table_info *private;
280         struct xt_action_param acpar;
281         unsigned int addend;
282
283         /* Initialization */
284         stackidx = 0;
285         indev = state->in ? state->in->name : nulldevname;
286         outdev = state->out ? state->out->name : nulldevname;
287         /* We handle fragments by dealing with the first fragment as
288          * if it was a normal packet.  All other fragments are treated
289          * normally, except that they will NEVER match rules that ask
290          * things we don't know, ie. tcp syn flag or ports).  If the
291          * rule is also a fragment-specific rule, non-fragments won't
292          * match it. */
293         acpar.fragoff = 0;
294         acpar.hotdrop = false;
295         acpar.net     = state->net;
296         acpar.in      = state->in;
297         acpar.out     = state->out;
298         acpar.family  = NFPROTO_IPV6;
299         acpar.hooknum = hook;
300
301         IP_NF_ASSERT(table->valid_hooks & (1 << hook));
302
303         local_bh_disable();
304         addend = xt_write_recseq_begin();
305         private = table->private;
306         /*
307          * Ensure we load private-> members after we've fetched the base
308          * pointer.
309          */
310         smp_read_barrier_depends();
311         cpu        = smp_processor_id();
312         table_base = private->entries;
313         jumpstack  = (struct ip6t_entry **)private->jumpstack[cpu];
314
315         /* Switch to alternate jumpstack if we're being invoked via TEE.
316          * TEE issues XT_CONTINUE verdict on original skb so we must not
317          * clobber the jumpstack.
318          *
319          * For recursion via REJECT or SYNPROXY the stack will be clobbered
320          * but it is no problem since absolute verdict is issued by these.
321          */
322         if (static_key_false(&xt_tee_enabled))
323                 jumpstack += private->stacksize * __this_cpu_read(nf_skb_duplicated);
324
325         e = get_entry(table_base, private->hook_entry[hook]);
326
327         do {
328                 const struct xt_entry_target *t;
329                 const struct xt_entry_match *ematch;
330                 struct xt_counters *counter;
331
332                 IP_NF_ASSERT(e);
333                 acpar.thoff = 0;
334                 if (!ip6_packet_match(skb, indev, outdev, &e->ipv6,
335                     &acpar.thoff, &acpar.fragoff, &acpar.hotdrop)) {
336  no_match:
337                         e = ip6t_next_entry(e);
338                         continue;
339                 }
340
341                 xt_ematch_foreach(ematch, e) {
342                         acpar.match     = ematch->u.kernel.match;
343                         acpar.matchinfo = ematch->data;
344                         if (!acpar.match->match(skb, &acpar))
345                                 goto no_match;
346                 }
347
348                 counter = xt_get_this_cpu_counter(&e->counters);
349                 ADD_COUNTER(*counter, skb->len, 1);
350
351                 t = ip6t_get_target_c(e);
352                 IP_NF_ASSERT(t->u.kernel.target);
353
354 #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE)
355                 /* The packet is traced: log it */
356                 if (unlikely(skb->nf_trace))
357                         trace_packet(state->net, skb, hook, state->in,
358                                      state->out, table->name, private, e);
359 #endif
360                 /* Standard target? */
361                 if (!t->u.kernel.target->target) {
362                         int v;
363
364                         v = ((struct xt_standard_target *)t)->verdict;
365                         if (v < 0) {
366                                 /* Pop from stack? */
367                                 if (v != XT_RETURN) {
368                                         verdict = (unsigned int)(-v) - 1;
369                                         break;
370                                 }
371                                 if (stackidx == 0)
372                                         e = get_entry(table_base,
373                                             private->underflow[hook]);
374                                 else
375                                         e = ip6t_next_entry(jumpstack[--stackidx]);
376                                 continue;
377                         }
378                         if (table_base + v != ip6t_next_entry(e) &&
379                             !(e->ipv6.flags & IP6T_F_GOTO)) {
380                                 if (unlikely(stackidx >= private->stacksize)) {
381                                         verdict = NF_DROP;
382                                         break;
383                                 }
384                                 jumpstack[stackidx++] = e;
385                         }
386
387                         e = get_entry(table_base, v);
388                         continue;
389                 }
390
391                 acpar.target   = t->u.kernel.target;
392                 acpar.targinfo = t->data;
393
394                 verdict = t->u.kernel.target->target(skb, &acpar);
395                 if (verdict == XT_CONTINUE)
396                         e = ip6t_next_entry(e);
397                 else
398                         /* Verdict */
399                         break;
400         } while (!acpar.hotdrop);
401
402         xt_write_recseq_end(addend);
403         local_bh_enable();
404
405         if (acpar.hotdrop)
406                 return NF_DROP;
407         else return verdict;
408 }
409
410 /* Figures out from what hook each rule can be called: returns 0 if
411    there are loops.  Puts hook bitmask in comefrom. */
412 static int
413 mark_source_chains(const struct xt_table_info *newinfo,
414                    unsigned int valid_hooks, void *entry0,
415                    unsigned int *offsets)
416 {
417         unsigned int hook;
418
419         /* No recursion; use packet counter to save back ptrs (reset
420            to 0 as we leave), and comefrom to save source hook bitmask */
421         for (hook = 0; hook < NF_INET_NUMHOOKS; hook++) {
422                 unsigned int pos = newinfo->hook_entry[hook];
423                 struct ip6t_entry *e = (struct ip6t_entry *)(entry0 + pos);
424
425                 if (!(valid_hooks & (1 << hook)))
426                         continue;
427
428                 /* Set initial back pointer. */
429                 e->counters.pcnt = pos;
430
431                 for (;;) {
432                         const struct xt_standard_target *t
433                                 = (void *)ip6t_get_target_c(e);
434                         int visited = e->comefrom & (1 << hook);
435
436                         if (e->comefrom & (1 << NF_INET_NUMHOOKS))
437                                 return 0;
438
439                         e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS));
440
441                         /* Unconditional return/END. */
442                         if ((unconditional(e) &&
443                              (strcmp(t->target.u.user.name,
444                                      XT_STANDARD_TARGET) == 0) &&
445                              t->verdict < 0) || visited) {
446                                 unsigned int oldpos, size;
447
448                                 if ((strcmp(t->target.u.user.name,
449                                             XT_STANDARD_TARGET) == 0) &&
450                                     t->verdict < -NF_MAX_VERDICT - 1)
451                                         return 0;
452
453                                 /* Return: backtrack through the last
454                                    big jump. */
455                                 do {
456                                         e->comefrom ^= (1<<NF_INET_NUMHOOKS);
457                                         oldpos = pos;
458                                         pos = e->counters.pcnt;
459                                         e->counters.pcnt = 0;
460
461                                         /* We're at the start. */
462                                         if (pos == oldpos)
463                                                 goto next;
464
465                                         e = (struct ip6t_entry *)
466                                                 (entry0 + pos);
467                                 } while (oldpos == pos + e->next_offset);
468
469                                 /* Move along one */
470                                 size = e->next_offset;
471                                 e = (struct ip6t_entry *)
472                                         (entry0 + pos + size);
473                                 if (pos + size >= newinfo->size)
474                                         return 0;
475                                 e->counters.pcnt = pos;
476                                 pos += size;
477                         } else {
478                                 int newpos = t->verdict;
479
480                                 if (strcmp(t->target.u.user.name,
481                                            XT_STANDARD_TARGET) == 0 &&
482                                     newpos >= 0) {
483                                         /* This a jump; chase it. */
484                                         if (!xt_find_jump_offset(offsets, newpos,
485                                                                  newinfo->number))
486                                                 return 0;
487                                         e = (struct ip6t_entry *)
488                                                 (entry0 + newpos);
489                                 } else {
490                                         /* ... this is a fallthru */
491                                         newpos = pos + e->next_offset;
492                                         if (newpos >= newinfo->size)
493                                                 return 0;
494                                 }
495                                 e = (struct ip6t_entry *)
496                                         (entry0 + newpos);
497                                 e->counters.pcnt = pos;
498                                 pos = newpos;
499                         }
500                 }
501 next:           ;
502         }
503         return 1;
504 }
505
506 static void cleanup_match(struct xt_entry_match *m, struct net *net)
507 {
508         struct xt_mtdtor_param par;
509
510         par.net       = net;
511         par.match     = m->u.kernel.match;
512         par.matchinfo = m->data;
513         par.family    = NFPROTO_IPV6;
514         if (par.match->destroy != NULL)
515                 par.match->destroy(&par);
516         module_put(par.match->me);
517 }
518
519 static int check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
520 {
521         const struct ip6t_ip6 *ipv6 = par->entryinfo;
522
523         par->match     = m->u.kernel.match;
524         par->matchinfo = m->data;
525
526         return xt_check_match(par, m->u.match_size - sizeof(*m),
527                               ipv6->proto, ipv6->invflags & IP6T_INV_PROTO);
528 }
529
530 static int
531 find_check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
532 {
533         struct xt_match *match;
534         int ret;
535
536         match = xt_request_find_match(NFPROTO_IPV6, m->u.user.name,
537                                       m->u.user.revision);
538         if (IS_ERR(match))
539                 return PTR_ERR(match);
540
541         m->u.kernel.match = match;
542
543         ret = check_match(m, par);
544         if (ret)
545                 goto err;
546
547         return 0;
548 err:
549         module_put(m->u.kernel.match->me);
550         return ret;
551 }
552
553 static int check_target(struct ip6t_entry *e, struct net *net, const char *name)
554 {
555         struct xt_entry_target *t = ip6t_get_target(e);
556         struct xt_tgchk_param par = {
557                 .net       = net,
558                 .table     = name,
559                 .entryinfo = e,
560                 .target    = t->u.kernel.target,
561                 .targinfo  = t->data,
562                 .hook_mask = e->comefrom,
563                 .family    = NFPROTO_IPV6,
564         };
565
566         t = ip6t_get_target(e);
567         return xt_check_target(&par, t->u.target_size - sizeof(*t),
568                                e->ipv6.proto,
569                                e->ipv6.invflags & IP6T_INV_PROTO);
570 }
571
572 static int
573 find_check_entry(struct ip6t_entry *e, struct net *net, const char *name,
574                  unsigned int size,
575                  struct xt_percpu_counter_alloc_state *alloc_state)
576 {
577         struct xt_entry_target *t;
578         struct xt_target *target;
579         int ret;
580         unsigned int j;
581         struct xt_mtchk_param mtpar;
582         struct xt_entry_match *ematch;
583
584         if (!xt_percpu_counter_alloc(alloc_state, &e->counters))
585                 return -ENOMEM;
586
587         j = 0;
588         memset(&mtpar, 0, sizeof(mtpar));
589         mtpar.net       = net;
590         mtpar.table     = name;
591         mtpar.entryinfo = &e->ipv6;
592         mtpar.hook_mask = e->comefrom;
593         mtpar.family    = NFPROTO_IPV6;
594         xt_ematch_foreach(ematch, e) {
595                 ret = find_check_match(ematch, &mtpar);
596                 if (ret != 0)
597                         goto cleanup_matches;
598                 ++j;
599         }
600
601         t = ip6t_get_target(e);
602         target = xt_request_find_target(NFPROTO_IPV6, t->u.user.name,
603                                         t->u.user.revision);
604         if (IS_ERR(target)) {
605                 ret = PTR_ERR(target);
606                 goto cleanup_matches;
607         }
608         t->u.kernel.target = target;
609
610         ret = check_target(e, net, name);
611         if (ret)
612                 goto err;
613         return 0;
614  err:
615         module_put(t->u.kernel.target->me);
616  cleanup_matches:
617         xt_ematch_foreach(ematch, e) {
618                 if (j-- == 0)
619                         break;
620                 cleanup_match(ematch, net);
621         }
622
623         xt_percpu_counter_free(&e->counters);
624
625         return ret;
626 }
627
628 static bool check_underflow(const struct ip6t_entry *e)
629 {
630         const struct xt_entry_target *t;
631         unsigned int verdict;
632
633         if (!unconditional(e))
634                 return false;
635         t = ip6t_get_target_c(e);
636         if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0)
637                 return false;
638         verdict = ((struct xt_standard_target *)t)->verdict;
639         verdict = -verdict - 1;
640         return verdict == NF_DROP || verdict == NF_ACCEPT;
641 }
642
643 static int
644 check_entry_size_and_hooks(struct ip6t_entry *e,
645                            struct xt_table_info *newinfo,
646                            const unsigned char *base,
647                            const unsigned char *limit,
648                            const unsigned int *hook_entries,
649                            const unsigned int *underflows,
650                            unsigned int valid_hooks)
651 {
652         unsigned int h;
653         int err;
654
655         if ((unsigned long)e % __alignof__(struct ip6t_entry) != 0 ||
656             (unsigned char *)e + sizeof(struct ip6t_entry) >= limit ||
657             (unsigned char *)e + e->next_offset > limit)
658                 return -EINVAL;
659
660         if (e->next_offset
661             < sizeof(struct ip6t_entry) + sizeof(struct xt_entry_target))
662                 return -EINVAL;
663
664         if (!ip6_checkentry(&e->ipv6))
665                 return -EINVAL;
666
667         err = xt_check_entry_offsets(e, e->elems, e->target_offset,
668                                      e->next_offset);
669         if (err)
670                 return err;
671
672         /* Check hooks & underflows */
673         for (h = 0; h < NF_INET_NUMHOOKS; h++) {
674                 if (!(valid_hooks & (1 << h)))
675                         continue;
676                 if ((unsigned char *)e - base == hook_entries[h])
677                         newinfo->hook_entry[h] = hook_entries[h];
678                 if ((unsigned char *)e - base == underflows[h]) {
679                         if (!check_underflow(e))
680                                 return -EINVAL;
681
682                         newinfo->underflow[h] = underflows[h];
683                 }
684         }
685
686         /* Clear counters and comefrom */
687         e->counters = ((struct xt_counters) { 0, 0 });
688         e->comefrom = 0;
689         return 0;
690 }
691
692 static void cleanup_entry(struct ip6t_entry *e, struct net *net)
693 {
694         struct xt_tgdtor_param par;
695         struct xt_entry_target *t;
696         struct xt_entry_match *ematch;
697
698         /* Cleanup all matches */
699         xt_ematch_foreach(ematch, e)
700                 cleanup_match(ematch, net);
701         t = ip6t_get_target(e);
702
703         par.net      = net;
704         par.target   = t->u.kernel.target;
705         par.targinfo = t->data;
706         par.family   = NFPROTO_IPV6;
707         if (par.target->destroy != NULL)
708                 par.target->destroy(&par);
709         module_put(par.target->me);
710         xt_percpu_counter_free(&e->counters);
711 }
712
713 /* Checks and translates the user-supplied table segment (held in
714    newinfo) */
715 static int
716 translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
717                 const struct ip6t_replace *repl)
718 {
719         struct xt_percpu_counter_alloc_state alloc_state = { 0 };
720         struct ip6t_entry *iter;
721         unsigned int *offsets;
722         unsigned int i;
723         int ret = 0;
724
725         newinfo->size = repl->size;
726         newinfo->number = repl->num_entries;
727
728         /* Init all hooks to impossible value. */
729         for (i = 0; i < NF_INET_NUMHOOKS; i++) {
730                 newinfo->hook_entry[i] = 0xFFFFFFFF;
731                 newinfo->underflow[i] = 0xFFFFFFFF;
732         }
733
734         offsets = xt_alloc_entry_offsets(newinfo->number);
735         if (!offsets)
736                 return -ENOMEM;
737         i = 0;
738         /* Walk through entries, checking offsets. */
739         xt_entry_foreach(iter, entry0, newinfo->size) {
740                 ret = check_entry_size_and_hooks(iter, newinfo, entry0,
741                                                  entry0 + repl->size,
742                                                  repl->hook_entry,
743                                                  repl->underflow,
744                                                  repl->valid_hooks);
745                 if (ret != 0)
746                         goto out_free;
747                 if (i < repl->num_entries)
748                         offsets[i] = (void *)iter - entry0;
749                 ++i;
750                 if (strcmp(ip6t_get_target(iter)->u.user.name,
751                     XT_ERROR_TARGET) == 0)
752                         ++newinfo->stacksize;
753         }
754
755         ret = -EINVAL;
756         if (i != repl->num_entries)
757                 goto out_free;
758
759         /* Check hooks all assigned */
760         for (i = 0; i < NF_INET_NUMHOOKS; i++) {
761                 /* Only hooks which are valid */
762                 if (!(repl->valid_hooks & (1 << i)))
763                         continue;
764                 if (newinfo->hook_entry[i] == 0xFFFFFFFF)
765                         goto out_free;
766                 if (newinfo->underflow[i] == 0xFFFFFFFF)
767                         goto out_free;
768         }
769
770         if (!mark_source_chains(newinfo, repl->valid_hooks, entry0, offsets)) {
771                 ret = -ELOOP;
772                 goto out_free;
773         }
774         kvfree(offsets);
775
776         /* Finally, each sanity check must pass */
777         i = 0;
778         xt_entry_foreach(iter, entry0, newinfo->size) {
779                 ret = find_check_entry(iter, net, repl->name, repl->size,
780                                        &alloc_state);
781                 if (ret != 0)
782                         break;
783                 ++i;
784         }
785
786         if (ret != 0) {
787                 xt_entry_foreach(iter, entry0, newinfo->size) {
788                         if (i-- == 0)
789                                 break;
790                         cleanup_entry(iter, net);
791                 }
792                 return ret;
793         }
794
795         return ret;
796  out_free:
797         kvfree(offsets);
798         return ret;
799 }
800
801 static void
802 get_counters(const struct xt_table_info *t,
803              struct xt_counters counters[])
804 {
805         struct ip6t_entry *iter;
806         unsigned int cpu;
807         unsigned int i;
808
809         for_each_possible_cpu(cpu) {
810                 seqcount_t *s = &per_cpu(xt_recseq, cpu);
811
812                 i = 0;
813                 xt_entry_foreach(iter, t->entries, t->size) {
814                         struct xt_counters *tmp;
815                         u64 bcnt, pcnt;
816                         unsigned int start;
817
818                         tmp = xt_get_per_cpu_counter(&iter->counters, cpu);
819                         do {
820                                 start = read_seqcount_begin(s);
821                                 bcnt = tmp->bcnt;
822                                 pcnt = tmp->pcnt;
823                         } while (read_seqcount_retry(s, start));
824
825                         ADD_COUNTER(counters[i], bcnt, pcnt);
826                         ++i;
827                 }
828         }
829 }
830
831 static struct xt_counters *alloc_counters(const struct xt_table *table)
832 {
833         unsigned int countersize;
834         struct xt_counters *counters;
835         const struct xt_table_info *private = table->private;
836
837         /* We need atomic snapshot of counters: rest doesn't change
838            (other than comefrom, which userspace doesn't care
839            about). */
840         countersize = sizeof(struct xt_counters) * private->number;
841         counters = vzalloc(countersize);
842
843         if (counters == NULL)
844                 return ERR_PTR(-ENOMEM);
845
846         get_counters(private, counters);
847
848         return counters;
849 }
850
851 static int
852 copy_entries_to_user(unsigned int total_size,
853                      const struct xt_table *table,
854                      void __user *userptr)
855 {
856         unsigned int off, num;
857         const struct ip6t_entry *e;
858         struct xt_counters *counters;
859         const struct xt_table_info *private = table->private;
860         int ret = 0;
861         const void *loc_cpu_entry;
862
863         counters = alloc_counters(table);
864         if (IS_ERR(counters))
865                 return PTR_ERR(counters);
866
867         loc_cpu_entry = private->entries;
868         if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) {
869                 ret = -EFAULT;
870                 goto free_counters;
871         }
872
873         /* FIXME: use iterator macros --RR */
874         /* ... then go back and fix counters and names */
875         for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){
876                 unsigned int i;
877                 const struct xt_entry_match *m;
878                 const struct xt_entry_target *t;
879
880                 e = (struct ip6t_entry *)(loc_cpu_entry + off);
881                 if (copy_to_user(userptr + off
882                                  + offsetof(struct ip6t_entry, counters),
883                                  &counters[num],
884                                  sizeof(counters[num])) != 0) {
885                         ret = -EFAULT;
886                         goto free_counters;
887                 }
888
889                 for (i = sizeof(struct ip6t_entry);
890                      i < e->target_offset;
891                      i += m->u.match_size) {
892                         m = (void *)e + i;
893
894                         if (copy_to_user(userptr + off + i
895                                          + offsetof(struct xt_entry_match,
896                                                     u.user.name),
897                                          m->u.kernel.match->name,
898                                          strlen(m->u.kernel.match->name)+1)
899                             != 0) {
900                                 ret = -EFAULT;
901                                 goto free_counters;
902                         }
903                 }
904
905                 t = ip6t_get_target_c(e);
906                 if (copy_to_user(userptr + off + e->target_offset
907                                  + offsetof(struct xt_entry_target,
908                                             u.user.name),
909                                  t->u.kernel.target->name,
910                                  strlen(t->u.kernel.target->name)+1) != 0) {
911                         ret = -EFAULT;
912                         goto free_counters;
913                 }
914         }
915
916  free_counters:
917         vfree(counters);
918         return ret;
919 }
920
921 #ifdef CONFIG_COMPAT
922 static void compat_standard_from_user(void *dst, const void *src)
923 {
924         int v = *(compat_int_t *)src;
925
926         if (v > 0)
927                 v += xt_compat_calc_jump(AF_INET6, v);
928         memcpy(dst, &v, sizeof(v));
929 }
930
931 static int compat_standard_to_user(void __user *dst, const void *src)
932 {
933         compat_int_t cv = *(int *)src;
934
935         if (cv > 0)
936                 cv -= xt_compat_calc_jump(AF_INET6, cv);
937         return copy_to_user(dst, &cv, sizeof(cv)) ? -EFAULT : 0;
938 }
939
940 static int compat_calc_entry(const struct ip6t_entry *e,
941                              const struct xt_table_info *info,
942                              const void *base, struct xt_table_info *newinfo)
943 {
944         const struct xt_entry_match *ematch;
945         const struct xt_entry_target *t;
946         unsigned int entry_offset;
947         int off, i, ret;
948
949         off = sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry);
950         entry_offset = (void *)e - base;
951         xt_ematch_foreach(ematch, e)
952                 off += xt_compat_match_offset(ematch->u.kernel.match);
953         t = ip6t_get_target_c(e);
954         off += xt_compat_target_offset(t->u.kernel.target);
955         newinfo->size -= off;
956         ret = xt_compat_add_offset(AF_INET6, entry_offset, off);
957         if (ret)
958                 return ret;
959
960         for (i = 0; i < NF_INET_NUMHOOKS; i++) {
961                 if (info->hook_entry[i] &&
962                     (e < (struct ip6t_entry *)(base + info->hook_entry[i])))
963                         newinfo->hook_entry[i] -= off;
964                 if (info->underflow[i] &&
965                     (e < (struct ip6t_entry *)(base + info->underflow[i])))
966                         newinfo->underflow[i] -= off;
967         }
968         return 0;
969 }
970
971 static int compat_table_info(const struct xt_table_info *info,
972                              struct xt_table_info *newinfo)
973 {
974         struct ip6t_entry *iter;
975         const void *loc_cpu_entry;
976         int ret;
977
978         if (!newinfo || !info)
979                 return -EINVAL;
980
981         /* we dont care about newinfo->entries */
982         memcpy(newinfo, info, offsetof(struct xt_table_info, entries));
983         newinfo->initial_entries = 0;
984         loc_cpu_entry = info->entries;
985         xt_compat_init_offsets(AF_INET6, info->number);
986         xt_entry_foreach(iter, loc_cpu_entry, info->size) {
987                 ret = compat_calc_entry(iter, info, loc_cpu_entry, newinfo);
988                 if (ret != 0)
989                         return ret;
990         }
991         return 0;
992 }
993 #endif
994
995 static int get_info(struct net *net, void __user *user,
996                     const int *len, int compat)
997 {
998         char name[XT_TABLE_MAXNAMELEN];
999         struct xt_table *t;
1000         int ret;
1001
1002         if (*len != sizeof(struct ip6t_getinfo))
1003                 return -EINVAL;
1004
1005         if (copy_from_user(name, user, sizeof(name)) != 0)
1006                 return -EFAULT;
1007
1008         name[XT_TABLE_MAXNAMELEN-1] = '\0';
1009 #ifdef CONFIG_COMPAT
1010         if (compat)
1011                 xt_compat_lock(AF_INET6);
1012 #endif
1013         t = try_then_request_module(xt_find_table_lock(net, AF_INET6, name),
1014                                     "ip6table_%s", name);
1015         if (!IS_ERR_OR_NULL(t)) {
1016                 struct ip6t_getinfo info;
1017                 const struct xt_table_info *private = t->private;
1018 #ifdef CONFIG_COMPAT
1019                 struct xt_table_info tmp;
1020
1021                 if (compat) {
1022                         ret = compat_table_info(private, &tmp);
1023                         xt_compat_flush_offsets(AF_INET6);
1024                         private = &tmp;
1025                 }
1026 #endif
1027                 memset(&info, 0, sizeof(info));
1028                 info.valid_hooks = t->valid_hooks;
1029                 memcpy(info.hook_entry, private->hook_entry,
1030                        sizeof(info.hook_entry));
1031                 memcpy(info.underflow, private->underflow,
1032                        sizeof(info.underflow));
1033                 info.num_entries = private->number;
1034                 info.size = private->size;
1035                 strcpy(info.name, name);
1036
1037                 if (copy_to_user(user, &info, *len) != 0)
1038                         ret = -EFAULT;
1039                 else
1040                         ret = 0;
1041
1042                 xt_table_unlock(t);
1043                 module_put(t->me);
1044         } else
1045                 ret = t ? PTR_ERR(t) : -ENOENT;
1046 #ifdef CONFIG_COMPAT
1047         if (compat)
1048                 xt_compat_unlock(AF_INET6);
1049 #endif
1050         return ret;
1051 }
1052
1053 static int
1054 get_entries(struct net *net, struct ip6t_get_entries __user *uptr,
1055             const int *len)
1056 {
1057         int ret;
1058         struct ip6t_get_entries get;
1059         struct xt_table *t;
1060
1061         if (*len < sizeof(get))
1062                 return -EINVAL;
1063         if (copy_from_user(&get, uptr, sizeof(get)) != 0)
1064                 return -EFAULT;
1065         if (*len != sizeof(struct ip6t_get_entries) + get.size)
1066                 return -EINVAL;
1067
1068         get.name[sizeof(get.name) - 1] = '\0';
1069
1070         t = xt_find_table_lock(net, AF_INET6, get.name);
1071         if (!IS_ERR_OR_NULL(t)) {
1072                 struct xt_table_info *private = t->private;
1073                 if (get.size == private->size)
1074                         ret = copy_entries_to_user(private->size,
1075                                                    t, uptr->entrytable);
1076                 else
1077                         ret = -EAGAIN;
1078
1079                 module_put(t->me);
1080                 xt_table_unlock(t);
1081         } else
1082                 ret = t ? PTR_ERR(t) : -ENOENT;
1083
1084         return ret;
1085 }
1086
1087 static int
1088 __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
1089              struct xt_table_info *newinfo, unsigned int num_counters,
1090              void __user *counters_ptr)
1091 {
1092         int ret;
1093         struct xt_table *t;
1094         struct xt_table_info *oldinfo;
1095         struct xt_counters *counters;
1096         struct ip6t_entry *iter;
1097
1098         ret = 0;
1099         counters = vzalloc(num_counters * sizeof(struct xt_counters));
1100         if (!counters) {
1101                 ret = -ENOMEM;
1102                 goto out;
1103         }
1104
1105         t = try_then_request_module(xt_find_table_lock(net, AF_INET6, name),
1106                                     "ip6table_%s", name);
1107         if (IS_ERR_OR_NULL(t)) {
1108                 ret = t ? PTR_ERR(t) : -ENOENT;
1109                 goto free_newinfo_counters_untrans;
1110         }
1111
1112         /* You lied! */
1113         if (valid_hooks != t->valid_hooks) {
1114                 ret = -EINVAL;
1115                 goto put_module;
1116         }
1117
1118         oldinfo = xt_replace_table(t, num_counters, newinfo, &ret);
1119         if (!oldinfo)
1120                 goto put_module;
1121
1122         /* Update module usage count based on number of rules */
1123         if ((oldinfo->number > oldinfo->initial_entries) ||
1124             (newinfo->number <= oldinfo->initial_entries))
1125                 module_put(t->me);
1126         if ((oldinfo->number > oldinfo->initial_entries) &&
1127             (newinfo->number <= oldinfo->initial_entries))
1128                 module_put(t->me);
1129
1130         /* Get the old counters, and synchronize with replace */
1131         get_counters(oldinfo, counters);
1132
1133         /* Decrease module usage counts and free resource */
1134         xt_entry_foreach(iter, oldinfo->entries, oldinfo->size)
1135                 cleanup_entry(iter, net);
1136
1137         xt_free_table_info(oldinfo);
1138         if (copy_to_user(counters_ptr, counters,
1139                          sizeof(struct xt_counters) * num_counters) != 0) {
1140                 /* Silent error, can't fail, new table is already in place */
1141                 net_warn_ratelimited("ip6tables: counters copy to user failed while replacing table\n");
1142         }
1143         vfree(counters);
1144         xt_table_unlock(t);
1145         return ret;
1146
1147  put_module:
1148         module_put(t->me);
1149         xt_table_unlock(t);
1150  free_newinfo_counters_untrans:
1151         vfree(counters);
1152  out:
1153         return ret;
1154 }
1155
1156 static int
1157 do_replace(struct net *net, const void __user *user, unsigned int len)
1158 {
1159         int ret;
1160         struct ip6t_replace tmp;
1161         struct xt_table_info *newinfo;
1162         void *loc_cpu_entry;
1163         struct ip6t_entry *iter;
1164
1165         if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
1166                 return -EFAULT;
1167
1168         /* overflow check */
1169         if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
1170                 return -ENOMEM;
1171         if (tmp.num_counters == 0)
1172                 return -EINVAL;
1173
1174         tmp.name[sizeof(tmp.name)-1] = 0;
1175
1176         newinfo = xt_alloc_table_info(tmp.size);
1177         if (!newinfo)
1178                 return -ENOMEM;
1179
1180         loc_cpu_entry = newinfo->entries;
1181         if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
1182                            tmp.size) != 0) {
1183                 ret = -EFAULT;
1184                 goto free_newinfo;
1185         }
1186
1187         ret = translate_table(net, newinfo, loc_cpu_entry, &tmp);
1188         if (ret != 0)
1189                 goto free_newinfo;
1190
1191         ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
1192                            tmp.num_counters, tmp.counters);
1193         if (ret)
1194                 goto free_newinfo_untrans;
1195         return 0;
1196
1197  free_newinfo_untrans:
1198         xt_entry_foreach(iter, loc_cpu_entry, newinfo->size)
1199                 cleanup_entry(iter, net);
1200  free_newinfo:
1201         xt_free_table_info(newinfo);
1202         return ret;
1203 }
1204
1205 static int
1206 do_add_counters(struct net *net, const void __user *user, unsigned int len,
1207                 int compat)
1208 {
1209         unsigned int i;
1210         struct xt_counters_info tmp;
1211         struct xt_counters *paddc;
1212         struct xt_table *t;
1213         const struct xt_table_info *private;
1214         int ret = 0;
1215         struct ip6t_entry *iter;
1216         unsigned int addend;
1217
1218         paddc = xt_copy_counters_from_user(user, len, &tmp, compat);
1219         if (IS_ERR(paddc))
1220                 return PTR_ERR(paddc);
1221         t = xt_find_table_lock(net, AF_INET6, tmp.name);
1222         if (IS_ERR_OR_NULL(t)) {
1223                 ret = t ? PTR_ERR(t) : -ENOENT;
1224                 goto free;
1225         }
1226
1227         local_bh_disable();
1228         private = t->private;
1229         if (private->number != tmp.num_counters) {
1230                 ret = -EINVAL;
1231                 goto unlock_up_free;
1232         }
1233
1234         i = 0;
1235         addend = xt_write_recseq_begin();
1236         xt_entry_foreach(iter, private->entries, private->size) {
1237                 struct xt_counters *tmp;
1238
1239                 tmp = xt_get_this_cpu_counter(&iter->counters);
1240                 ADD_COUNTER(*tmp, paddc[i].bcnt, paddc[i].pcnt);
1241                 ++i;
1242         }
1243         xt_write_recseq_end(addend);
1244  unlock_up_free:
1245         local_bh_enable();
1246         xt_table_unlock(t);
1247         module_put(t->me);
1248  free:
1249         vfree(paddc);
1250
1251         return ret;
1252 }
1253
1254 #ifdef CONFIG_COMPAT
1255 struct compat_ip6t_replace {
1256         char                    name[XT_TABLE_MAXNAMELEN];
1257         u32                     valid_hooks;
1258         u32                     num_entries;
1259         u32                     size;
1260         u32                     hook_entry[NF_INET_NUMHOOKS];
1261         u32                     underflow[NF_INET_NUMHOOKS];
1262         u32                     num_counters;
1263         compat_uptr_t           counters;       /* struct xt_counters * */
1264         struct compat_ip6t_entry entries[0];
1265 };
1266
1267 static int
1268 compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr,
1269                           unsigned int *size, struct xt_counters *counters,
1270                           unsigned int i)
1271 {
1272         struct xt_entry_target *t;
1273         struct compat_ip6t_entry __user *ce;
1274         u_int16_t target_offset, next_offset;
1275         compat_uint_t origsize;
1276         const struct xt_entry_match *ematch;
1277         int ret = 0;
1278
1279         origsize = *size;
1280         ce = (struct compat_ip6t_entry __user *)*dstptr;
1281         if (copy_to_user(ce, e, sizeof(struct ip6t_entry)) != 0 ||
1282             copy_to_user(&ce->counters, &counters[i],
1283             sizeof(counters[i])) != 0)
1284                 return -EFAULT;
1285
1286         *dstptr += sizeof(struct compat_ip6t_entry);
1287         *size -= sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry);
1288
1289         xt_ematch_foreach(ematch, e) {
1290                 ret = xt_compat_match_to_user(ematch, dstptr, size);
1291                 if (ret != 0)
1292                         return ret;
1293         }
1294         target_offset = e->target_offset - (origsize - *size);
1295         t = ip6t_get_target(e);
1296         ret = xt_compat_target_to_user(t, dstptr, size);
1297         if (ret)
1298                 return ret;
1299         next_offset = e->next_offset - (origsize - *size);
1300         if (put_user(target_offset, &ce->target_offset) != 0 ||
1301             put_user(next_offset, &ce->next_offset) != 0)
1302                 return -EFAULT;
1303         return 0;
1304 }
1305
1306 static int
1307 compat_find_calc_match(struct xt_entry_match *m,
1308                        const struct ip6t_ip6 *ipv6,
1309                        int *size)
1310 {
1311         struct xt_match *match;
1312
1313         match = xt_request_find_match(NFPROTO_IPV6, m->u.user.name,
1314                                       m->u.user.revision);
1315         if (IS_ERR(match))
1316                 return PTR_ERR(match);
1317
1318         m->u.kernel.match = match;
1319         *size += xt_compat_match_offset(match);
1320         return 0;
1321 }
1322
1323 static void compat_release_entry(struct compat_ip6t_entry *e)
1324 {
1325         struct xt_entry_target *t;
1326         struct xt_entry_match *ematch;
1327
1328         /* Cleanup all matches */
1329         xt_ematch_foreach(ematch, e)
1330                 module_put(ematch->u.kernel.match->me);
1331         t = compat_ip6t_get_target(e);
1332         module_put(t->u.kernel.target->me);
1333 }
1334
1335 static int
1336 check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
1337                                   struct xt_table_info *newinfo,
1338                                   unsigned int *size,
1339                                   const unsigned char *base,
1340                                   const unsigned char *limit)
1341 {
1342         struct xt_entry_match *ematch;
1343         struct xt_entry_target *t;
1344         struct xt_target *target;
1345         unsigned int entry_offset;
1346         unsigned int j;
1347         int ret, off;
1348
1349         if ((unsigned long)e % __alignof__(struct compat_ip6t_entry) != 0 ||
1350             (unsigned char *)e + sizeof(struct compat_ip6t_entry) >= limit ||
1351             (unsigned char *)e + e->next_offset > limit)
1352                 return -EINVAL;
1353
1354         if (e->next_offset < sizeof(struct compat_ip6t_entry) +
1355                              sizeof(struct compat_xt_entry_target))
1356                 return -EINVAL;
1357
1358         if (!ip6_checkentry(&e->ipv6))
1359                 return -EINVAL;
1360
1361         ret = xt_compat_check_entry_offsets(e, e->elems,
1362                                             e->target_offset, e->next_offset);
1363         if (ret)
1364                 return ret;
1365
1366         off = sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry);
1367         entry_offset = (void *)e - (void *)base;
1368         j = 0;
1369         xt_ematch_foreach(ematch, e) {
1370                 ret = compat_find_calc_match(ematch, &e->ipv6, &off);
1371                 if (ret != 0)
1372                         goto release_matches;
1373                 ++j;
1374         }
1375
1376         t = compat_ip6t_get_target(e);
1377         target = xt_request_find_target(NFPROTO_IPV6, t->u.user.name,
1378                                         t->u.user.revision);
1379         if (IS_ERR(target)) {
1380                 ret = PTR_ERR(target);
1381                 goto release_matches;
1382         }
1383         t->u.kernel.target = target;
1384
1385         off += xt_compat_target_offset(target);
1386         *size += off;
1387         ret = xt_compat_add_offset(AF_INET6, entry_offset, off);
1388         if (ret)
1389                 goto out;
1390
1391         return 0;
1392
1393 out:
1394         module_put(t->u.kernel.target->me);
1395 release_matches:
1396         xt_ematch_foreach(ematch, e) {
1397                 if (j-- == 0)
1398                         break;
1399                 module_put(ematch->u.kernel.match->me);
1400         }
1401         return ret;
1402 }
1403
1404 static void
1405 compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
1406                             unsigned int *size,
1407                             struct xt_table_info *newinfo, unsigned char *base)
1408 {
1409         struct xt_entry_target *t;
1410         struct ip6t_entry *de;
1411         unsigned int origsize;
1412         int h;
1413         struct xt_entry_match *ematch;
1414
1415         origsize = *size;
1416         de = (struct ip6t_entry *)*dstptr;
1417         memcpy(de, e, sizeof(struct ip6t_entry));
1418         memcpy(&de->counters, &e->counters, sizeof(e->counters));
1419
1420         *dstptr += sizeof(struct ip6t_entry);
1421         *size += sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry);
1422
1423         xt_ematch_foreach(ematch, e)
1424                 xt_compat_match_from_user(ematch, dstptr, size);
1425
1426         de->target_offset = e->target_offset - (origsize - *size);
1427         t = compat_ip6t_get_target(e);
1428         xt_compat_target_from_user(t, dstptr, size);
1429
1430         de->next_offset = e->next_offset - (origsize - *size);
1431         for (h = 0; h < NF_INET_NUMHOOKS; h++) {
1432                 if ((unsigned char *)de - base < newinfo->hook_entry[h])
1433                         newinfo->hook_entry[h] -= origsize - *size;
1434                 if ((unsigned char *)de - base < newinfo->underflow[h])
1435                         newinfo->underflow[h] -= origsize - *size;
1436         }
1437 }
1438
1439 static int
1440 translate_compat_table(struct net *net,
1441                        struct xt_table_info **pinfo,
1442                        void **pentry0,
1443                        const struct compat_ip6t_replace *compatr)
1444 {
1445         unsigned int i, j;
1446         struct xt_table_info *newinfo, *info;
1447         void *pos, *entry0, *entry1;
1448         struct compat_ip6t_entry *iter0;
1449         struct ip6t_replace repl;
1450         unsigned int size;
1451         int ret = 0;
1452
1453         info = *pinfo;
1454         entry0 = *pentry0;
1455         size = compatr->size;
1456         info->number = compatr->num_entries;
1457
1458         j = 0;
1459         xt_compat_lock(AF_INET6);
1460         xt_compat_init_offsets(AF_INET6, compatr->num_entries);
1461         /* Walk through entries, checking offsets. */
1462         xt_entry_foreach(iter0, entry0, compatr->size) {
1463                 ret = check_compat_entry_size_and_hooks(iter0, info, &size,
1464                                                         entry0,
1465                                                         entry0 + compatr->size);
1466                 if (ret != 0)
1467                         goto out_unlock;
1468                 ++j;
1469         }
1470
1471         ret = -EINVAL;
1472         if (j != compatr->num_entries)
1473                 goto out_unlock;
1474
1475         ret = -ENOMEM;
1476         newinfo = xt_alloc_table_info(size);
1477         if (!newinfo)
1478                 goto out_unlock;
1479
1480         memset(newinfo->entries, 0, size);
1481
1482         newinfo->number = compatr->num_entries;
1483         for (i = 0; i < NF_INET_NUMHOOKS; i++) {
1484                 newinfo->hook_entry[i] = compatr->hook_entry[i];
1485                 newinfo->underflow[i] = compatr->underflow[i];
1486         }
1487         entry1 = newinfo->entries;
1488         pos = entry1;
1489         size = compatr->size;
1490         xt_entry_foreach(iter0, entry0, compatr->size)
1491                 compat_copy_entry_from_user(iter0, &pos, &size,
1492                                             newinfo, entry1);
1493
1494         /* all module references in entry0 are now gone. */
1495         xt_compat_flush_offsets(AF_INET6);
1496         xt_compat_unlock(AF_INET6);
1497
1498         memcpy(&repl, compatr, sizeof(*compatr));
1499
1500         for (i = 0; i < NF_INET_NUMHOOKS; i++) {
1501                 repl.hook_entry[i] = newinfo->hook_entry[i];
1502                 repl.underflow[i] = newinfo->underflow[i];
1503         }
1504
1505         repl.num_counters = 0;
1506         repl.counters = NULL;
1507         repl.size = newinfo->size;
1508         ret = translate_table(net, newinfo, entry1, &repl);
1509         if (ret)
1510                 goto free_newinfo;
1511
1512         *pinfo = newinfo;
1513         *pentry0 = entry1;
1514         xt_free_table_info(info);
1515         return 0;
1516
1517 free_newinfo:
1518         xt_free_table_info(newinfo);
1519         return ret;
1520 out_unlock:
1521         xt_compat_flush_offsets(AF_INET6);
1522         xt_compat_unlock(AF_INET6);
1523         xt_entry_foreach(iter0, entry0, compatr->size) {
1524                 if (j-- == 0)
1525                         break;
1526                 compat_release_entry(iter0);
1527         }
1528         return ret;
1529 }
1530
1531 static int
1532 compat_do_replace(struct net *net, void __user *user, unsigned int len)
1533 {
1534         int ret;
1535         struct compat_ip6t_replace tmp;
1536         struct xt_table_info *newinfo;
1537         void *loc_cpu_entry;
1538         struct ip6t_entry *iter;
1539
1540         if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
1541                 return -EFAULT;
1542
1543         /* overflow check */
1544         if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
1545                 return -ENOMEM;
1546         if (tmp.num_counters == 0)
1547                 return -EINVAL;
1548
1549         tmp.name[sizeof(tmp.name)-1] = 0;
1550
1551         newinfo = xt_alloc_table_info(tmp.size);
1552         if (!newinfo)
1553                 return -ENOMEM;
1554
1555         loc_cpu_entry = newinfo->entries;
1556         if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
1557                            tmp.size) != 0) {
1558                 ret = -EFAULT;
1559                 goto free_newinfo;
1560         }
1561
1562         ret = translate_compat_table(net, &newinfo, &loc_cpu_entry, &tmp);
1563         if (ret != 0)
1564                 goto free_newinfo;
1565
1566         ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
1567                            tmp.num_counters, compat_ptr(tmp.counters));
1568         if (ret)
1569                 goto free_newinfo_untrans;
1570         return 0;
1571
1572  free_newinfo_untrans:
1573         xt_entry_foreach(iter, loc_cpu_entry, newinfo->size)
1574                 cleanup_entry(iter, net);
1575  free_newinfo:
1576         xt_free_table_info(newinfo);
1577         return ret;
1578 }
1579
1580 static int
1581 compat_do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user,
1582                        unsigned int len)
1583 {
1584         int ret;
1585
1586         if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
1587                 return -EPERM;
1588
1589         switch (cmd) {
1590         case IP6T_SO_SET_REPLACE:
1591                 ret = compat_do_replace(sock_net(sk), user, len);
1592                 break;
1593
1594         case IP6T_SO_SET_ADD_COUNTERS:
1595                 ret = do_add_counters(sock_net(sk), user, len, 1);
1596                 break;
1597
1598         default:
1599                 ret = -EINVAL;
1600         }
1601
1602         return ret;
1603 }
1604
1605 struct compat_ip6t_get_entries {
1606         char name[XT_TABLE_MAXNAMELEN];
1607         compat_uint_t size;
1608         struct compat_ip6t_entry entrytable[0];
1609 };
1610
1611 static int
1612 compat_copy_entries_to_user(unsigned int total_size, struct xt_table *table,
1613                             void __user *userptr)
1614 {
1615         struct xt_counters *counters;
1616         const struct xt_table_info *private = table->private;
1617         void __user *pos;
1618         unsigned int size;
1619         int ret = 0;
1620         unsigned int i = 0;
1621         struct ip6t_entry *iter;
1622
1623         counters = alloc_counters(table);
1624         if (IS_ERR(counters))
1625                 return PTR_ERR(counters);
1626
1627         pos = userptr;
1628         size = total_size;
1629         xt_entry_foreach(iter, private->entries, total_size) {
1630                 ret = compat_copy_entry_to_user(iter, &pos,
1631                                                 &size, counters, i++);
1632                 if (ret != 0)
1633                         break;
1634         }
1635
1636         vfree(counters);
1637         return ret;
1638 }
1639
1640 static int
1641 compat_get_entries(struct net *net, struct compat_ip6t_get_entries __user *uptr,
1642                    int *len)
1643 {
1644         int ret;
1645         struct compat_ip6t_get_entries get;
1646         struct xt_table *t;
1647
1648         if (*len < sizeof(get))
1649                 return -EINVAL;
1650
1651         if (copy_from_user(&get, uptr, sizeof(get)) != 0)
1652                 return -EFAULT;
1653
1654         if (*len != sizeof(struct compat_ip6t_get_entries) + get.size)
1655                 return -EINVAL;
1656
1657         get.name[sizeof(get.name) - 1] = '\0';
1658
1659         xt_compat_lock(AF_INET6);
1660         t = xt_find_table_lock(net, AF_INET6, get.name);
1661         if (!IS_ERR_OR_NULL(t)) {
1662                 const struct xt_table_info *private = t->private;
1663                 struct xt_table_info info;
1664                 ret = compat_table_info(private, &info);
1665                 if (!ret && get.size == info.size)
1666                         ret = compat_copy_entries_to_user(private->size,
1667                                                           t, uptr->entrytable);
1668                 else if (!ret)
1669                         ret = -EAGAIN;
1670
1671                 xt_compat_flush_offsets(AF_INET6);
1672                 module_put(t->me);
1673                 xt_table_unlock(t);
1674         } else
1675                 ret = t ? PTR_ERR(t) : -ENOENT;
1676
1677         xt_compat_unlock(AF_INET6);
1678         return ret;
1679 }
1680
1681 static int do_ip6t_get_ctl(struct sock *, int, void __user *, int *);
1682
1683 static int
1684 compat_do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
1685 {
1686         int ret;
1687
1688         if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
1689                 return -EPERM;
1690
1691         switch (cmd) {
1692         case IP6T_SO_GET_INFO:
1693                 ret = get_info(sock_net(sk), user, len, 1);
1694                 break;
1695         case IP6T_SO_GET_ENTRIES:
1696                 ret = compat_get_entries(sock_net(sk), user, len);
1697                 break;
1698         default:
1699                 ret = do_ip6t_get_ctl(sk, cmd, user, len);
1700         }
1701         return ret;
1702 }
1703 #endif
1704
1705 static int
1706 do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
1707 {
1708         int ret;
1709
1710         if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
1711                 return -EPERM;
1712
1713         switch (cmd) {
1714         case IP6T_SO_SET_REPLACE:
1715                 ret = do_replace(sock_net(sk), user, len);
1716                 break;
1717
1718         case IP6T_SO_SET_ADD_COUNTERS:
1719                 ret = do_add_counters(sock_net(sk), user, len, 0);
1720                 break;
1721
1722         default:
1723                 ret = -EINVAL;
1724         }
1725
1726         return ret;
1727 }
1728
1729 static int
1730 do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
1731 {
1732         int ret;
1733
1734         if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
1735                 return -EPERM;
1736
1737         switch (cmd) {
1738         case IP6T_SO_GET_INFO:
1739                 ret = get_info(sock_net(sk), user, len, 0);
1740                 break;
1741
1742         case IP6T_SO_GET_ENTRIES:
1743                 ret = get_entries(sock_net(sk), user, len);
1744                 break;
1745
1746         case IP6T_SO_GET_REVISION_MATCH:
1747         case IP6T_SO_GET_REVISION_TARGET: {
1748                 struct xt_get_revision rev;
1749                 int target;
1750
1751                 if (*len != sizeof(rev)) {
1752                         ret = -EINVAL;
1753                         break;
1754                 }
1755                 if (copy_from_user(&rev, user, sizeof(rev)) != 0) {
1756                         ret = -EFAULT;
1757                         break;
1758                 }
1759                 rev.name[sizeof(rev.name)-1] = 0;
1760
1761                 if (cmd == IP6T_SO_GET_REVISION_TARGET)
1762                         target = 1;
1763                 else
1764                         target = 0;
1765
1766                 try_then_request_module(xt_find_revision(AF_INET6, rev.name,
1767                                                          rev.revision,
1768                                                          target, &ret),
1769                                         "ip6t_%s", rev.name);
1770                 break;
1771         }
1772
1773         default:
1774                 ret = -EINVAL;
1775         }
1776
1777         return ret;
1778 }
1779
1780 static void __ip6t_unregister_table(struct net *net, struct xt_table *table)
1781 {
1782         struct xt_table_info *private;
1783         void *loc_cpu_entry;
1784         struct module *table_owner = table->me;
1785         struct ip6t_entry *iter;
1786
1787         private = xt_unregister_table(table);
1788
1789         /* Decrease module usage counts and free resources */
1790         loc_cpu_entry = private->entries;
1791         xt_entry_foreach(iter, loc_cpu_entry, private->size)
1792                 cleanup_entry(iter, net);
1793         if (private->number > private->initial_entries)
1794                 module_put(table_owner);
1795         xt_free_table_info(private);
1796 }
1797
1798 int ip6t_register_table(struct net *net, const struct xt_table *table,
1799                         const struct ip6t_replace *repl,
1800                         const struct nf_hook_ops *ops,
1801                         struct xt_table **res)
1802 {
1803         int ret;
1804         struct xt_table_info *newinfo;
1805         struct xt_table_info bootstrap = {0};
1806         void *loc_cpu_entry;
1807         struct xt_table *new_table;
1808
1809         newinfo = xt_alloc_table_info(repl->size);
1810         if (!newinfo)
1811                 return -ENOMEM;
1812
1813         loc_cpu_entry = newinfo->entries;
1814         memcpy(loc_cpu_entry, repl->entries, repl->size);
1815
1816         ret = translate_table(net, newinfo, loc_cpu_entry, repl);
1817         if (ret != 0)
1818                 goto out_free;
1819
1820         new_table = xt_register_table(net, table, &bootstrap, newinfo);
1821         if (IS_ERR(new_table)) {
1822                 ret = PTR_ERR(new_table);
1823                 goto out_free;
1824         }
1825
1826         /* set res now, will see skbs right after nf_register_net_hooks */
1827         WRITE_ONCE(*res, new_table);
1828
1829         ret = nf_register_net_hooks(net, ops, hweight32(table->valid_hooks));
1830         if (ret != 0) {
1831                 __ip6t_unregister_table(net, new_table);
1832                 *res = NULL;
1833         }
1834
1835         return ret;
1836
1837 out_free:
1838         xt_free_table_info(newinfo);
1839         return ret;
1840 }
1841
1842 void ip6t_unregister_table(struct net *net, struct xt_table *table,
1843                            const struct nf_hook_ops *ops)
1844 {
1845         nf_unregister_net_hooks(net, ops, hweight32(table->valid_hooks));
1846         __ip6t_unregister_table(net, table);
1847 }
1848
1849 /* Returns 1 if the type and code is matched by the range, 0 otherwise */
1850 static inline bool
1851 icmp6_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code,
1852                      u_int8_t type, u_int8_t code,
1853                      bool invert)
1854 {
1855         return (type == test_type && code >= min_code && code <= max_code)
1856                 ^ invert;
1857 }
1858
1859 static bool
1860 icmp6_match(const struct sk_buff *skb, struct xt_action_param *par)
1861 {
1862         const struct icmp6hdr *ic;
1863         struct icmp6hdr _icmph;
1864         const struct ip6t_icmp *icmpinfo = par->matchinfo;
1865
1866         /* Must not be a fragment. */
1867         if (par->fragoff != 0)
1868                 return false;
1869
1870         ic = skb_header_pointer(skb, par->thoff, sizeof(_icmph), &_icmph);
1871         if (ic == NULL) {
1872                 /* We've been asked to examine this packet, and we
1873                  * can't.  Hence, no choice but to drop.
1874                  */
1875                 par->hotdrop = true;
1876                 return false;
1877         }
1878
1879         return icmp6_type_code_match(icmpinfo->type,
1880                                      icmpinfo->code[0],
1881                                      icmpinfo->code[1],
1882                                      ic->icmp6_type, ic->icmp6_code,
1883                                      !!(icmpinfo->invflags&IP6T_ICMP_INV));
1884 }
1885
1886 /* Called when user tries to insert an entry of this type. */
1887 static int icmp6_checkentry(const struct xt_mtchk_param *par)
1888 {
1889         const struct ip6t_icmp *icmpinfo = par->matchinfo;
1890
1891         /* Must specify no unknown invflags */
1892         return (icmpinfo->invflags & ~IP6T_ICMP_INV) ? -EINVAL : 0;
1893 }
1894
1895 /* The built-in targets: standard (NULL) and error. */
1896 static struct xt_target ip6t_builtin_tg[] __read_mostly = {
1897         {
1898                 .name             = XT_STANDARD_TARGET,
1899                 .targetsize       = sizeof(int),
1900                 .family           = NFPROTO_IPV6,
1901 #ifdef CONFIG_COMPAT
1902                 .compatsize       = sizeof(compat_int_t),
1903                 .compat_from_user = compat_standard_from_user,
1904                 .compat_to_user   = compat_standard_to_user,
1905 #endif
1906         },
1907         {
1908                 .name             = XT_ERROR_TARGET,
1909                 .target           = ip6t_error,
1910                 .targetsize       = XT_FUNCTION_MAXNAMELEN,
1911                 .family           = NFPROTO_IPV6,
1912         },
1913 };
1914
1915 static struct nf_sockopt_ops ip6t_sockopts = {
1916         .pf             = PF_INET6,
1917         .set_optmin     = IP6T_BASE_CTL,
1918         .set_optmax     = IP6T_SO_SET_MAX+1,
1919         .set            = do_ip6t_set_ctl,
1920 #ifdef CONFIG_COMPAT
1921         .compat_set     = compat_do_ip6t_set_ctl,
1922 #endif
1923         .get_optmin     = IP6T_BASE_CTL,
1924         .get_optmax     = IP6T_SO_GET_MAX+1,
1925         .get            = do_ip6t_get_ctl,
1926 #ifdef CONFIG_COMPAT
1927         .compat_get     = compat_do_ip6t_get_ctl,
1928 #endif
1929         .owner          = THIS_MODULE,
1930 };
1931
1932 static struct xt_match ip6t_builtin_mt[] __read_mostly = {
1933         {
1934                 .name       = "icmp6",
1935                 .match      = icmp6_match,
1936                 .matchsize  = sizeof(struct ip6t_icmp),
1937                 .checkentry = icmp6_checkentry,
1938                 .proto      = IPPROTO_ICMPV6,
1939                 .family     = NFPROTO_IPV6,
1940                 .me         = THIS_MODULE,
1941         },
1942 };
1943
1944 static int __net_init ip6_tables_net_init(struct net *net)
1945 {
1946         return xt_proto_init(net, NFPROTO_IPV6);
1947 }
1948
1949 static void __net_exit ip6_tables_net_exit(struct net *net)
1950 {
1951         xt_proto_fini(net, NFPROTO_IPV6);
1952 }
1953
1954 static struct pernet_operations ip6_tables_net_ops = {
1955         .init = ip6_tables_net_init,
1956         .exit = ip6_tables_net_exit,
1957 };
1958
1959 static int __init ip6_tables_init(void)
1960 {
1961         int ret;
1962
1963         ret = register_pernet_subsys(&ip6_tables_net_ops);
1964         if (ret < 0)
1965                 goto err1;
1966
1967         /* No one else will be downing sem now, so we won't sleep */
1968         ret = xt_register_targets(ip6t_builtin_tg, ARRAY_SIZE(ip6t_builtin_tg));
1969         if (ret < 0)
1970                 goto err2;
1971         ret = xt_register_matches(ip6t_builtin_mt, ARRAY_SIZE(ip6t_builtin_mt));
1972         if (ret < 0)
1973                 goto err4;
1974
1975         /* Register setsockopt */
1976         ret = nf_register_sockopt(&ip6t_sockopts);
1977         if (ret < 0)
1978                 goto err5;
1979
1980         pr_info("(C) 2000-2006 Netfilter Core Team\n");
1981         return 0;
1982
1983 err5:
1984         xt_unregister_matches(ip6t_builtin_mt, ARRAY_SIZE(ip6t_builtin_mt));
1985 err4:
1986         xt_unregister_targets(ip6t_builtin_tg, ARRAY_SIZE(ip6t_builtin_tg));
1987 err2:
1988         unregister_pernet_subsys(&ip6_tables_net_ops);
1989 err1:
1990         return ret;
1991 }
1992
1993 static void __exit ip6_tables_fini(void)
1994 {
1995         nf_unregister_sockopt(&ip6t_sockopts);
1996
1997         xt_unregister_matches(ip6t_builtin_mt, ARRAY_SIZE(ip6t_builtin_mt));
1998         xt_unregister_targets(ip6t_builtin_tg, ARRAY_SIZE(ip6t_builtin_tg));
1999         unregister_pernet_subsys(&ip6_tables_net_ops);
2000 }
2001
2002 EXPORT_SYMBOL(ip6t_register_table);
2003 EXPORT_SYMBOL(ip6t_unregister_table);
2004 EXPORT_SYMBOL(ip6t_do_table);
2005
2006 module_init(ip6_tables_init);
2007 module_exit(ip6_tables_fini);