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