Fix common misspellings
[linux-flexiantxendom0-3.2.10.git] / net / ipv4 / netfilter / ip_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  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  */
11 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12 #include <linux/cache.h>
13 #include <linux/capability.h>
14 #include <linux/skbuff.h>
15 #include <linux/kmod.h>
16 #include <linux/vmalloc.h>
17 #include <linux/netdevice.h>
18 #include <linux/module.h>
19 #include <linux/icmp.h>
20 #include <net/ip.h>
21 #include <net/compat.h>
22 #include <asm/uaccess.h>
23 #include <linux/mutex.h>
24 #include <linux/proc_fs.h>
25 #include <linux/err.h>
26 #include <linux/cpumask.h>
27
28 #include <linux/netfilter/x_tables.h>
29 #include <linux/netfilter_ipv4/ip_tables.h>
30 #include <net/netfilter/nf_log.h>
31 #include "../../netfilter/xt_repldata.h"
32
33 MODULE_LICENSE("GPL");
34 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
35 MODULE_DESCRIPTION("IPv4 packet filter");
36
37 /*#define DEBUG_IP_FIREWALL*/
38 /*#define DEBUG_ALLOW_ALL*/ /* Useful for remote debugging */
39 /*#define DEBUG_IP_FIREWALL_USER*/
40
41 #ifdef DEBUG_IP_FIREWALL
42 #define dprintf(format, args...) pr_info(format , ## args)
43 #else
44 #define dprintf(format, args...)
45 #endif
46
47 #ifdef DEBUG_IP_FIREWALL_USER
48 #define duprintf(format, args...) pr_info(format , ## args)
49 #else
50 #define duprintf(format, args...)
51 #endif
52
53 #ifdef CONFIG_NETFILTER_DEBUG
54 #define IP_NF_ASSERT(x)         WARN_ON(!(x))
55 #else
56 #define IP_NF_ASSERT(x)
57 #endif
58
59 #if 0
60 /* All the better to debug you with... */
61 #define static
62 #define inline
63 #endif
64
65 void *ipt_alloc_initial_table(const struct xt_table *info)
66 {
67         return xt_alloc_initial_table(ipt, IPT);
68 }
69 EXPORT_SYMBOL_GPL(ipt_alloc_initial_table);
70
71 /*
72    We keep a set of rules for each CPU, so we can avoid write-locking
73    them in the softirq when updating the counters and therefore
74    only need to read-lock in the softirq; doing a write_lock_bh() in user
75    context stops packets coming through and allows user context to read
76    the counters or update the rules.
77
78    Hence the start of any table is given by get_table() below.  */
79
80 /* Returns whether matches rule or not. */
81 /* Performance critical - called for every packet */
82 static inline bool
83 ip_packet_match(const struct iphdr *ip,
84                 const char *indev,
85                 const char *outdev,
86                 const struct ipt_ip *ipinfo,
87                 int isfrag)
88 {
89         unsigned long ret;
90
91 #define FWINV(bool, invflg) ((bool) ^ !!(ipinfo->invflags & (invflg)))
92
93         if (FWINV((ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr,
94                   IPT_INV_SRCIP) ||
95             FWINV((ip->daddr&ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr,
96                   IPT_INV_DSTIP)) {
97                 dprintf("Source or dest mismatch.\n");
98
99                 dprintf("SRC: %pI4. Mask: %pI4. Target: %pI4.%s\n",
100                         &ip->saddr, &ipinfo->smsk.s_addr, &ipinfo->src.s_addr,
101                         ipinfo->invflags & IPT_INV_SRCIP ? " (INV)" : "");
102                 dprintf("DST: %pI4 Mask: %pI4 Target: %pI4.%s\n",
103                         &ip->daddr, &ipinfo->dmsk.s_addr, &ipinfo->dst.s_addr,
104                         ipinfo->invflags & IPT_INV_DSTIP ? " (INV)" : "");
105                 return false;
106         }
107
108         ret = ifname_compare_aligned(indev, ipinfo->iniface, ipinfo->iniface_mask);
109
110         if (FWINV(ret != 0, IPT_INV_VIA_IN)) {
111                 dprintf("VIA in mismatch (%s vs %s).%s\n",
112                         indev, ipinfo->iniface,
113                         ipinfo->invflags&IPT_INV_VIA_IN ?" (INV)":"");
114                 return false;
115         }
116
117         ret = ifname_compare_aligned(outdev, ipinfo->outiface, ipinfo->outiface_mask);
118
119         if (FWINV(ret != 0, IPT_INV_VIA_OUT)) {
120                 dprintf("VIA out mismatch (%s vs %s).%s\n",
121                         outdev, ipinfo->outiface,
122                         ipinfo->invflags&IPT_INV_VIA_OUT ?" (INV)":"");
123                 return false;
124         }
125
126         /* Check specific protocol */
127         if (ipinfo->proto &&
128             FWINV(ip->protocol != ipinfo->proto, IPT_INV_PROTO)) {
129                 dprintf("Packet protocol %hi does not match %hi.%s\n",
130                         ip->protocol, ipinfo->proto,
131                         ipinfo->invflags&IPT_INV_PROTO ? " (INV)":"");
132                 return false;
133         }
134
135         /* If we have a fragment rule but the packet is not a fragment
136          * then we return zero */
137         if (FWINV((ipinfo->flags&IPT_F_FRAG) && !isfrag, IPT_INV_FRAG)) {
138                 dprintf("Fragment rule but not fragment.%s\n",
139                         ipinfo->invflags & IPT_INV_FRAG ? " (INV)" : "");
140                 return false;
141         }
142
143         return true;
144 }
145
146 static bool
147 ip_checkentry(const struct ipt_ip *ip)
148 {
149         if (ip->flags & ~IPT_F_MASK) {
150                 duprintf("Unknown flag bits set: %08X\n",
151                          ip->flags & ~IPT_F_MASK);
152                 return false;
153         }
154         if (ip->invflags & ~IPT_INV_MASK) {
155                 duprintf("Unknown invflag bits set: %08X\n",
156                          ip->invflags & ~IPT_INV_MASK);
157                 return false;
158         }
159         return true;
160 }
161
162 static unsigned int
163 ipt_error(struct sk_buff *skb, const struct xt_action_param *par)
164 {
165         if (net_ratelimit())
166                 pr_info("error: `%s'\n", (const char *)par->targinfo);
167
168         return NF_DROP;
169 }
170
171 /* Performance critical */
172 static inline struct ipt_entry *
173 get_entry(const void *base, unsigned int offset)
174 {
175         return (struct ipt_entry *)(base + offset);
176 }
177
178 /* All zeroes == unconditional rule. */
179 /* Mildly perf critical (only if packet tracing is on) */
180 static inline bool unconditional(const struct ipt_ip *ip)
181 {
182         static const struct ipt_ip uncond;
183
184         return memcmp(ip, &uncond, sizeof(uncond)) == 0;
185 #undef FWINV
186 }
187
188 /* for const-correctness */
189 static inline const struct xt_entry_target *
190 ipt_get_target_c(const struct ipt_entry *e)
191 {
192         return ipt_get_target((struct ipt_entry *)e);
193 }
194
195 #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
196     defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
197 static const char *const hooknames[] = {
198         [NF_INET_PRE_ROUTING]           = "PREROUTING",
199         [NF_INET_LOCAL_IN]              = "INPUT",
200         [NF_INET_FORWARD]               = "FORWARD",
201         [NF_INET_LOCAL_OUT]             = "OUTPUT",
202         [NF_INET_POST_ROUTING]          = "POSTROUTING",
203 };
204
205 enum nf_ip_trace_comments {
206         NF_IP_TRACE_COMMENT_RULE,
207         NF_IP_TRACE_COMMENT_RETURN,
208         NF_IP_TRACE_COMMENT_POLICY,
209 };
210
211 static const char *const comments[] = {
212         [NF_IP_TRACE_COMMENT_RULE]      = "rule",
213         [NF_IP_TRACE_COMMENT_RETURN]    = "return",
214         [NF_IP_TRACE_COMMENT_POLICY]    = "policy",
215 };
216
217 static struct nf_loginfo trace_loginfo = {
218         .type = NF_LOG_TYPE_LOG,
219         .u = {
220                 .log = {
221                         .level = 4,
222                         .logflags = NF_LOG_MASK,
223                 },
224         },
225 };
226
227 /* Mildly perf critical (only if packet tracing is on) */
228 static inline int
229 get_chainname_rulenum(const struct ipt_entry *s, const struct ipt_entry *e,
230                       const char *hookname, const char **chainname,
231                       const char **comment, unsigned int *rulenum)
232 {
233         const struct xt_standard_target *t = (void *)ipt_get_target_c(s);
234
235         if (strcmp(t->target.u.kernel.target->name, XT_ERROR_TARGET) == 0) {
236                 /* Head of user chain: ERROR target with chainname */
237                 *chainname = t->target.data;
238                 (*rulenum) = 0;
239         } else if (s == e) {
240                 (*rulenum)++;
241
242                 if (s->target_offset == sizeof(struct ipt_entry) &&
243                     strcmp(t->target.u.kernel.target->name,
244                            XT_STANDARD_TARGET) == 0 &&
245                    t->verdict < 0 &&
246                    unconditional(&s->ip)) {
247                         /* Tail of chains: STANDARD target (return/policy) */
248                         *comment = *chainname == hookname
249                                 ? comments[NF_IP_TRACE_COMMENT_POLICY]
250                                 : comments[NF_IP_TRACE_COMMENT_RETURN];
251                 }
252                 return 1;
253         } else
254                 (*rulenum)++;
255
256         return 0;
257 }
258
259 static void trace_packet(const struct sk_buff *skb,
260                          unsigned int hook,
261                          const struct net_device *in,
262                          const struct net_device *out,
263                          const char *tablename,
264                          const struct xt_table_info *private,
265                          const struct ipt_entry *e)
266 {
267         const void *table_base;
268         const struct ipt_entry *root;
269         const char *hookname, *chainname, *comment;
270         const struct ipt_entry *iter;
271         unsigned int rulenum = 0;
272
273         table_base = private->entries[smp_processor_id()];
274         root = get_entry(table_base, private->hook_entry[hook]);
275
276         hookname = chainname = hooknames[hook];
277         comment = comments[NF_IP_TRACE_COMMENT_RULE];
278
279         xt_entry_foreach(iter, root, private->size - private->hook_entry[hook])
280                 if (get_chainname_rulenum(iter, e, hookname,
281                     &chainname, &comment, &rulenum) != 0)
282                         break;
283
284         nf_log_packet(AF_INET, hook, skb, in, out, &trace_loginfo,
285                       "TRACE: %s:%s:%s:%u ",
286                       tablename, chainname, comment, rulenum);
287 }
288 #endif
289
290 static inline __pure
291 struct ipt_entry *ipt_next_entry(const struct ipt_entry *entry)
292 {
293         return (void *)entry + entry->next_offset;
294 }
295
296 /* Returns one of the generic firewall policies, like NF_ACCEPT. */
297 unsigned int
298 ipt_do_table(struct sk_buff *skb,
299              unsigned int hook,
300              const struct net_device *in,
301              const struct net_device *out,
302              struct xt_table *table)
303 {
304         static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
305         const struct iphdr *ip;
306         /* Initializing verdict to NF_DROP keeps gcc happy. */
307         unsigned int verdict = NF_DROP;
308         const char *indev, *outdev;
309         const void *table_base;
310         struct ipt_entry *e, **jumpstack;
311         unsigned int *stackptr, origptr, cpu;
312         const struct xt_table_info *private;
313         struct xt_action_param acpar;
314
315         /* Initialization */
316         ip = ip_hdr(skb);
317         indev = in ? in->name : nulldevname;
318         outdev = out ? out->name : nulldevname;
319         /* We handle fragments by dealing with the first fragment as
320          * if it was a normal packet.  All other fragments are treated
321          * normally, except that they will NEVER match rules that ask
322          * things we don't know, ie. tcp syn flag or ports).  If the
323          * rule is also a fragment-specific rule, non-fragments won't
324          * match it. */
325         acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
326         acpar.thoff   = ip_hdrlen(skb);
327         acpar.hotdrop = false;
328         acpar.in      = in;
329         acpar.out     = out;
330         acpar.family  = NFPROTO_IPV4;
331         acpar.hooknum = hook;
332
333         IP_NF_ASSERT(table->valid_hooks & (1 << hook));
334         xt_info_rdlock_bh();
335         private = table->private;
336         cpu        = smp_processor_id();
337         table_base = private->entries[cpu];
338         jumpstack  = (struct ipt_entry **)private->jumpstack[cpu];
339         stackptr   = per_cpu_ptr(private->stackptr, cpu);
340         origptr    = *stackptr;
341
342         e = get_entry(table_base, private->hook_entry[hook]);
343
344         pr_debug("Entering %s(hook %u); sp at %u (UF %p)\n",
345                  table->name, hook, origptr,
346                  get_entry(table_base, private->underflow[hook]));
347
348         do {
349                 const struct xt_entry_target *t;
350                 const struct xt_entry_match *ematch;
351
352                 IP_NF_ASSERT(e);
353                 if (!ip_packet_match(ip, indev, outdev,
354                     &e->ip, acpar.fragoff)) {
355  no_match:
356                         e = ipt_next_entry(e);
357                         continue;
358                 }
359
360                 xt_ematch_foreach(ematch, e) {
361                         acpar.match     = ematch->u.kernel.match;
362                         acpar.matchinfo = ematch->data;
363                         if (!acpar.match->match(skb, &acpar))
364                                 goto no_match;
365                 }
366
367                 ADD_COUNTER(e->counters, skb->len, 1);
368
369                 t = ipt_get_target(e);
370                 IP_NF_ASSERT(t->u.kernel.target);
371
372 #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
373     defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
374                 /* The packet is traced: log it */
375                 if (unlikely(skb->nf_trace))
376                         trace_packet(skb, hook, in, out,
377                                      table->name, private, e);
378 #endif
379                 /* Standard target? */
380                 if (!t->u.kernel.target->target) {
381                         int v;
382
383                         v = ((struct xt_standard_target *)t)->verdict;
384                         if (v < 0) {
385                                 /* Pop from stack? */
386                                 if (v != XT_RETURN) {
387                                         verdict = (unsigned)(-v) - 1;
388                                         break;
389                                 }
390                                 if (*stackptr <= origptr) {
391                                         e = get_entry(table_base,
392                                             private->underflow[hook]);
393                                         pr_debug("Underflow (this is normal) "
394                                                  "to %p\n", e);
395                                 } else {
396                                         e = jumpstack[--*stackptr];
397                                         pr_debug("Pulled %p out from pos %u\n",
398                                                  e, *stackptr);
399                                         e = ipt_next_entry(e);
400                                 }
401                                 continue;
402                         }
403                         if (table_base + v != ipt_next_entry(e) &&
404                             !(e->ip.flags & IPT_F_GOTO)) {
405                                 if (*stackptr >= private->stacksize) {
406                                         verdict = NF_DROP;
407                                         break;
408                                 }
409                                 jumpstack[(*stackptr)++] = e;
410                                 pr_debug("Pushed %p into pos %u\n",
411                                          e, *stackptr - 1);
412                         }
413
414                         e = get_entry(table_base, v);
415                         continue;
416                 }
417
418                 acpar.target   = t->u.kernel.target;
419                 acpar.targinfo = t->data;
420
421                 verdict = t->u.kernel.target->target(skb, &acpar);
422                 /* Target might have changed stuff. */
423                 ip = ip_hdr(skb);
424                 if (verdict == XT_CONTINUE)
425                         e = ipt_next_entry(e);
426                 else
427                         /* Verdict */
428                         break;
429         } while (!acpar.hotdrop);
430         pr_debug("Exiting %s; resetting sp from %u to %u\n",
431                  __func__, *stackptr, origptr);
432         *stackptr = origptr;
433         xt_info_rdunlock_bh();
434 #ifdef DEBUG_ALLOW_ALL
435         return NF_ACCEPT;
436 #else
437         if (acpar.hotdrop)
438                 return NF_DROP;
439         else return verdict;
440 #endif
441 }
442
443 /* Figures out from what hook each rule can be called: returns 0 if
444    there are loops.  Puts hook bitmask in comefrom. */
445 static int
446 mark_source_chains(const struct xt_table_info *newinfo,
447                    unsigned int valid_hooks, void *entry0)
448 {
449         unsigned int hook;
450
451         /* No recursion; use packet counter to save back ptrs (reset
452            to 0 as we leave), and comefrom to save source hook bitmask */
453         for (hook = 0; hook < NF_INET_NUMHOOKS; hook++) {
454                 unsigned int pos = newinfo->hook_entry[hook];
455                 struct ipt_entry *e = (struct ipt_entry *)(entry0 + pos);
456
457                 if (!(valid_hooks & (1 << hook)))
458                         continue;
459
460                 /* Set initial back pointer. */
461                 e->counters.pcnt = pos;
462
463                 for (;;) {
464                         const struct xt_standard_target *t
465                                 = (void *)ipt_get_target_c(e);
466                         int visited = e->comefrom & (1 << hook);
467
468                         if (e->comefrom & (1 << NF_INET_NUMHOOKS)) {
469                                 pr_err("iptables: loop hook %u pos %u %08X.\n",
470                                        hook, pos, e->comefrom);
471                                 return 0;
472                         }
473                         e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS));
474
475                         /* Unconditional return/END. */
476                         if ((e->target_offset == sizeof(struct ipt_entry) &&
477                              (strcmp(t->target.u.user.name,
478                                      XT_STANDARD_TARGET) == 0) &&
479                              t->verdict < 0 && unconditional(&e->ip)) ||
480                             visited) {
481                                 unsigned int oldpos, size;
482
483                                 if ((strcmp(t->target.u.user.name,
484                                             XT_STANDARD_TARGET) == 0) &&
485                                     t->verdict < -NF_MAX_VERDICT - 1) {
486                                         duprintf("mark_source_chains: bad "
487                                                 "negative verdict (%i)\n",
488                                                                 t->verdict);
489                                         return 0;
490                                 }
491
492                                 /* Return: backtrack through the last
493                                    big jump. */
494                                 do {
495                                         e->comefrom ^= (1<<NF_INET_NUMHOOKS);
496 #ifdef DEBUG_IP_FIREWALL_USER
497                                         if (e->comefrom
498                                             & (1 << NF_INET_NUMHOOKS)) {
499                                                 duprintf("Back unset "
500                                                          "on hook %u "
501                                                          "rule %u\n",
502                                                          hook, pos);
503                                         }
504 #endif
505                                         oldpos = pos;
506                                         pos = e->counters.pcnt;
507                                         e->counters.pcnt = 0;
508
509                                         /* We're at the start. */
510                                         if (pos == oldpos)
511                                                 goto next;
512
513                                         e = (struct ipt_entry *)
514                                                 (entry0 + pos);
515                                 } while (oldpos == pos + e->next_offset);
516
517                                 /* Move along one */
518                                 size = e->next_offset;
519                                 e = (struct ipt_entry *)
520                                         (entry0 + pos + size);
521                                 e->counters.pcnt = pos;
522                                 pos += size;
523                         } else {
524                                 int newpos = t->verdict;
525
526                                 if (strcmp(t->target.u.user.name,
527                                            XT_STANDARD_TARGET) == 0 &&
528                                     newpos >= 0) {
529                                         if (newpos > newinfo->size -
530                                                 sizeof(struct ipt_entry)) {
531                                                 duprintf("mark_source_chains: "
532                                                         "bad verdict (%i)\n",
533                                                                 newpos);
534                                                 return 0;
535                                         }
536                                         /* This a jump; chase it. */
537                                         duprintf("Jump rule %u -> %u\n",
538                                                  pos, newpos);
539                                 } else {
540                                         /* ... this is a fallthru */
541                                         newpos = pos + e->next_offset;
542                                 }
543                                 e = (struct ipt_entry *)
544                                         (entry0 + newpos);
545                                 e->counters.pcnt = pos;
546                                 pos = newpos;
547                         }
548                 }
549                 next:
550                 duprintf("Finished chain %u\n", hook);
551         }
552         return 1;
553 }
554
555 static void cleanup_match(struct xt_entry_match *m, struct net *net)
556 {
557         struct xt_mtdtor_param par;
558
559         par.net       = net;
560         par.match     = m->u.kernel.match;
561         par.matchinfo = m->data;
562         par.family    = NFPROTO_IPV4;
563         if (par.match->destroy != NULL)
564                 par.match->destroy(&par);
565         module_put(par.match->me);
566 }
567
568 static int
569 check_entry(const struct ipt_entry *e, const char *name)
570 {
571         const struct xt_entry_target *t;
572
573         if (!ip_checkentry(&e->ip)) {
574                 duprintf("ip check failed %p %s.\n", e, par->match->name);
575                 return -EINVAL;
576         }
577
578         if (e->target_offset + sizeof(struct xt_entry_target) >
579             e->next_offset)
580                 return -EINVAL;
581
582         t = ipt_get_target_c(e);
583         if (e->target_offset + t->u.target_size > e->next_offset)
584                 return -EINVAL;
585
586         return 0;
587 }
588
589 static int
590 check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
591 {
592         const struct ipt_ip *ip = par->entryinfo;
593         int ret;
594
595         par->match     = m->u.kernel.match;
596         par->matchinfo = m->data;
597
598         ret = xt_check_match(par, m->u.match_size - sizeof(*m),
599               ip->proto, ip->invflags & IPT_INV_PROTO);
600         if (ret < 0) {
601                 duprintf("check failed for `%s'.\n", par->match->name);
602                 return ret;
603         }
604         return 0;
605 }
606
607 static int
608 find_check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
609 {
610         struct xt_match *match;
611         int ret;
612
613         match = xt_request_find_match(NFPROTO_IPV4, m->u.user.name,
614                                       m->u.user.revision);
615         if (IS_ERR(match)) {
616                 duprintf("find_check_match: `%s' not found\n", m->u.user.name);
617                 return PTR_ERR(match);
618         }
619         m->u.kernel.match = match;
620
621         ret = check_match(m, par);
622         if (ret)
623                 goto err;
624
625         return 0;
626 err:
627         module_put(m->u.kernel.match->me);
628         return ret;
629 }
630
631 static int check_target(struct ipt_entry *e, struct net *net, const char *name)
632 {
633         struct xt_entry_target *t = ipt_get_target(e);
634         struct xt_tgchk_param par = {
635                 .net       = net,
636                 .table     = name,
637                 .entryinfo = e,
638                 .target    = t->u.kernel.target,
639                 .targinfo  = t->data,
640                 .hook_mask = e->comefrom,
641                 .family    = NFPROTO_IPV4,
642         };
643         int ret;
644
645         ret = xt_check_target(&par, t->u.target_size - sizeof(*t),
646               e->ip.proto, e->ip.invflags & IPT_INV_PROTO);
647         if (ret < 0) {
648                 duprintf("check failed for `%s'.\n",
649                          t->u.kernel.target->name);
650                 return ret;
651         }
652         return 0;
653 }
654
655 static int
656 find_check_entry(struct ipt_entry *e, struct net *net, const char *name,
657                  unsigned int size)
658 {
659         struct xt_entry_target *t;
660         struct xt_target *target;
661         int ret;
662         unsigned int j;
663         struct xt_mtchk_param mtpar;
664         struct xt_entry_match *ematch;
665
666         ret = check_entry(e, name);
667         if (ret)
668                 return ret;
669
670         j = 0;
671         mtpar.net       = net;
672         mtpar.table     = name;
673         mtpar.entryinfo = &e->ip;
674         mtpar.hook_mask = e->comefrom;
675         mtpar.family    = NFPROTO_IPV4;
676         xt_ematch_foreach(ematch, e) {
677                 ret = find_check_match(ematch, &mtpar);
678                 if (ret != 0)
679                         goto cleanup_matches;
680                 ++j;
681         }
682
683         t = ipt_get_target(e);
684         target = xt_request_find_target(NFPROTO_IPV4, t->u.user.name,
685                                         t->u.user.revision);
686         if (IS_ERR(target)) {
687                 duprintf("find_check_entry: `%s' not found\n", t->u.user.name);
688                 ret = PTR_ERR(target);
689                 goto cleanup_matches;
690         }
691         t->u.kernel.target = target;
692
693         ret = check_target(e, net, name);
694         if (ret)
695                 goto err;
696         return 0;
697  err:
698         module_put(t->u.kernel.target->me);
699  cleanup_matches:
700         xt_ematch_foreach(ematch, e) {
701                 if (j-- == 0)
702                         break;
703                 cleanup_match(ematch, net);
704         }
705         return ret;
706 }
707
708 static bool check_underflow(const struct ipt_entry *e)
709 {
710         const struct xt_entry_target *t;
711         unsigned int verdict;
712
713         if (!unconditional(&e->ip))
714                 return false;
715         t = ipt_get_target_c(e);
716         if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0)
717                 return false;
718         verdict = ((struct xt_standard_target *)t)->verdict;
719         verdict = -verdict - 1;
720         return verdict == NF_DROP || verdict == NF_ACCEPT;
721 }
722
723 static int
724 check_entry_size_and_hooks(struct ipt_entry *e,
725                            struct xt_table_info *newinfo,
726                            const unsigned char *base,
727                            const unsigned char *limit,
728                            const unsigned int *hook_entries,
729                            const unsigned int *underflows,
730                            unsigned int valid_hooks)
731 {
732         unsigned int h;
733
734         if ((unsigned long)e % __alignof__(struct ipt_entry) != 0 ||
735             (unsigned char *)e + sizeof(struct ipt_entry) >= limit) {
736                 duprintf("Bad offset %p\n", e);
737                 return -EINVAL;
738         }
739
740         if (e->next_offset
741             < sizeof(struct ipt_entry) + sizeof(struct xt_entry_target)) {
742                 duprintf("checking: element %p size %u\n",
743                          e, e->next_offset);
744                 return -EINVAL;
745         }
746
747         /* Check hooks & underflows */
748         for (h = 0; h < NF_INET_NUMHOOKS; h++) {
749                 if (!(valid_hooks & (1 << h)))
750                         continue;
751                 if ((unsigned char *)e - base == hook_entries[h])
752                         newinfo->hook_entry[h] = hook_entries[h];
753                 if ((unsigned char *)e - base == underflows[h]) {
754                         if (!check_underflow(e)) {
755                                 pr_err("Underflows must be unconditional and "
756                                        "use the STANDARD target with "
757                                        "ACCEPT/DROP\n");
758                                 return -EINVAL;
759                         }
760                         newinfo->underflow[h] = underflows[h];
761                 }
762         }
763
764         /* Clear counters and comefrom */
765         e->counters = ((struct xt_counters) { 0, 0 });
766         e->comefrom = 0;
767         return 0;
768 }
769
770 static void
771 cleanup_entry(struct ipt_entry *e, struct net *net)
772 {
773         struct xt_tgdtor_param par;
774         struct xt_entry_target *t;
775         struct xt_entry_match *ematch;
776
777         /* Cleanup all matches */
778         xt_ematch_foreach(ematch, e)
779                 cleanup_match(ematch, net);
780         t = ipt_get_target(e);
781
782         par.net      = net;
783         par.target   = t->u.kernel.target;
784         par.targinfo = t->data;
785         par.family   = NFPROTO_IPV4;
786         if (par.target->destroy != NULL)
787                 par.target->destroy(&par);
788         module_put(par.target->me);
789 }
790
791 /* Checks and translates the user-supplied table segment (held in
792    newinfo) */
793 static int
794 translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
795                 const struct ipt_replace *repl)
796 {
797         struct ipt_entry *iter;
798         unsigned int i;
799         int ret = 0;
800
801         newinfo->size = repl->size;
802         newinfo->number = repl->num_entries;
803
804         /* Init all hooks to impossible value. */
805         for (i = 0; i < NF_INET_NUMHOOKS; i++) {
806                 newinfo->hook_entry[i] = 0xFFFFFFFF;
807                 newinfo->underflow[i] = 0xFFFFFFFF;
808         }
809
810         duprintf("translate_table: size %u\n", newinfo->size);
811         i = 0;
812         /* Walk through entries, checking offsets. */
813         xt_entry_foreach(iter, entry0, newinfo->size) {
814                 ret = check_entry_size_and_hooks(iter, newinfo, entry0,
815                                                  entry0 + repl->size,
816                                                  repl->hook_entry,
817                                                  repl->underflow,
818                                                  repl->valid_hooks);
819                 if (ret != 0)
820                         return ret;
821                 ++i;
822                 if (strcmp(ipt_get_target(iter)->u.user.name,
823                     XT_ERROR_TARGET) == 0)
824                         ++newinfo->stacksize;
825         }
826
827         if (i != repl->num_entries) {
828                 duprintf("translate_table: %u not %u entries\n",
829                          i, repl->num_entries);
830                 return -EINVAL;
831         }
832
833         /* Check hooks all assigned */
834         for (i = 0; i < NF_INET_NUMHOOKS; i++) {
835                 /* Only hooks which are valid */
836                 if (!(repl->valid_hooks & (1 << i)))
837                         continue;
838                 if (newinfo->hook_entry[i] == 0xFFFFFFFF) {
839                         duprintf("Invalid hook entry %u %u\n",
840                                  i, repl->hook_entry[i]);
841                         return -EINVAL;
842                 }
843                 if (newinfo->underflow[i] == 0xFFFFFFFF) {
844                         duprintf("Invalid underflow %u %u\n",
845                                  i, repl->underflow[i]);
846                         return -EINVAL;
847                 }
848         }
849
850         if (!mark_source_chains(newinfo, repl->valid_hooks, entry0))
851                 return -ELOOP;
852
853         /* Finally, each sanity check must pass */
854         i = 0;
855         xt_entry_foreach(iter, entry0, newinfo->size) {
856                 ret = find_check_entry(iter, net, repl->name, repl->size);
857                 if (ret != 0)
858                         break;
859                 ++i;
860         }
861
862         if (ret != 0) {
863                 xt_entry_foreach(iter, entry0, newinfo->size) {
864                         if (i-- == 0)
865                                 break;
866                         cleanup_entry(iter, net);
867                 }
868                 return ret;
869         }
870
871         /* And one copy for every other CPU */
872         for_each_possible_cpu(i) {
873                 if (newinfo->entries[i] && newinfo->entries[i] != entry0)
874                         memcpy(newinfo->entries[i], entry0, newinfo->size);
875         }
876
877         return ret;
878 }
879
880 static void
881 get_counters(const struct xt_table_info *t,
882              struct xt_counters counters[])
883 {
884         struct ipt_entry *iter;
885         unsigned int cpu;
886         unsigned int i;
887
888         for_each_possible_cpu(cpu) {
889                 seqlock_t *lock = &per_cpu(xt_info_locks, cpu).lock;
890
891                 i = 0;
892                 xt_entry_foreach(iter, t->entries[cpu], t->size) {
893                         u64 bcnt, pcnt;
894                         unsigned int start;
895
896                         do {
897                                 start = read_seqbegin(lock);
898                                 bcnt = iter->counters.bcnt;
899                                 pcnt = iter->counters.pcnt;
900                         } while (read_seqretry(lock, start));
901
902                         ADD_COUNTER(counters[i], bcnt, pcnt);
903                         ++i; /* macro does multi eval of i */
904                 }
905         }
906 }
907
908 static struct xt_counters *alloc_counters(const struct xt_table *table)
909 {
910         unsigned int countersize;
911         struct xt_counters *counters;
912         const struct xt_table_info *private = table->private;
913
914         /* We need atomic snapshot of counters: rest doesn't change
915            (other than comefrom, which userspace doesn't care
916            about). */
917         countersize = sizeof(struct xt_counters) * private->number;
918         counters = vzalloc(countersize);
919
920         if (counters == NULL)
921                 return ERR_PTR(-ENOMEM);
922
923         get_counters(private, counters);
924
925         return counters;
926 }
927
928 static int
929 copy_entries_to_user(unsigned int total_size,
930                      const struct xt_table *table,
931                      void __user *userptr)
932 {
933         unsigned int off, num;
934         const struct ipt_entry *e;
935         struct xt_counters *counters;
936         const struct xt_table_info *private = table->private;
937         int ret = 0;
938         const void *loc_cpu_entry;
939
940         counters = alloc_counters(table);
941         if (IS_ERR(counters))
942                 return PTR_ERR(counters);
943
944         /* choose the copy that is on our node/cpu, ...
945          * This choice is lazy (because current thread is
946          * allowed to migrate to another cpu)
947          */
948         loc_cpu_entry = private->entries[raw_smp_processor_id()];
949         if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) {
950                 ret = -EFAULT;
951                 goto free_counters;
952         }
953
954         /* FIXME: use iterator macros --RR */
955         /* ... then go back and fix counters and names */
956         for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){
957                 unsigned int i;
958                 const struct xt_entry_match *m;
959                 const struct xt_entry_target *t;
960
961                 e = (struct ipt_entry *)(loc_cpu_entry + off);
962                 if (copy_to_user(userptr + off
963                                  + offsetof(struct ipt_entry, counters),
964                                  &counters[num],
965                                  sizeof(counters[num])) != 0) {
966                         ret = -EFAULT;
967                         goto free_counters;
968                 }
969
970                 for (i = sizeof(struct ipt_entry);
971                      i < e->target_offset;
972                      i += m->u.match_size) {
973                         m = (void *)e + i;
974
975                         if (copy_to_user(userptr + off + i
976                                          + offsetof(struct xt_entry_match,
977                                                     u.user.name),
978                                          m->u.kernel.match->name,
979                                          strlen(m->u.kernel.match->name)+1)
980                             != 0) {
981                                 ret = -EFAULT;
982                                 goto free_counters;
983                         }
984                 }
985
986                 t = ipt_get_target_c(e);
987                 if (copy_to_user(userptr + off + e->target_offset
988                                  + offsetof(struct xt_entry_target,
989                                             u.user.name),
990                                  t->u.kernel.target->name,
991                                  strlen(t->u.kernel.target->name)+1) != 0) {
992                         ret = -EFAULT;
993                         goto free_counters;
994                 }
995         }
996
997  free_counters:
998         vfree(counters);
999         return ret;
1000 }
1001
1002 #ifdef CONFIG_COMPAT
1003 static void compat_standard_from_user(void *dst, const void *src)
1004 {
1005         int v = *(compat_int_t *)src;
1006
1007         if (v > 0)
1008                 v += xt_compat_calc_jump(AF_INET, v);
1009         memcpy(dst, &v, sizeof(v));
1010 }
1011
1012 static int compat_standard_to_user(void __user *dst, const void *src)
1013 {
1014         compat_int_t cv = *(int *)src;
1015
1016         if (cv > 0)
1017                 cv -= xt_compat_calc_jump(AF_INET, cv);
1018         return copy_to_user(dst, &cv, sizeof(cv)) ? -EFAULT : 0;
1019 }
1020
1021 static int compat_calc_entry(const struct ipt_entry *e,
1022                              const struct xt_table_info *info,
1023                              const void *base, struct xt_table_info *newinfo)
1024 {
1025         const struct xt_entry_match *ematch;
1026         const struct xt_entry_target *t;
1027         unsigned int entry_offset;
1028         int off, i, ret;
1029
1030         off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
1031         entry_offset = (void *)e - base;
1032         xt_ematch_foreach(ematch, e)
1033                 off += xt_compat_match_offset(ematch->u.kernel.match);
1034         t = ipt_get_target_c(e);
1035         off += xt_compat_target_offset(t->u.kernel.target);
1036         newinfo->size -= off;
1037         ret = xt_compat_add_offset(AF_INET, entry_offset, off);
1038         if (ret)
1039                 return ret;
1040
1041         for (i = 0; i < NF_INET_NUMHOOKS; i++) {
1042                 if (info->hook_entry[i] &&
1043                     (e < (struct ipt_entry *)(base + info->hook_entry[i])))
1044                         newinfo->hook_entry[i] -= off;
1045                 if (info->underflow[i] &&
1046                     (e < (struct ipt_entry *)(base + info->underflow[i])))
1047                         newinfo->underflow[i] -= off;
1048         }
1049         return 0;
1050 }
1051
1052 static int compat_table_info(const struct xt_table_info *info,
1053                              struct xt_table_info *newinfo)
1054 {
1055         struct ipt_entry *iter;
1056         void *loc_cpu_entry;
1057         int ret;
1058
1059         if (!newinfo || !info)
1060                 return -EINVAL;
1061
1062         /* we dont care about newinfo->entries[] */
1063         memcpy(newinfo, info, offsetof(struct xt_table_info, entries));
1064         newinfo->initial_entries = 0;
1065         loc_cpu_entry = info->entries[raw_smp_processor_id()];
1066         xt_compat_init_offsets(AF_INET, info->number);
1067         xt_entry_foreach(iter, loc_cpu_entry, info->size) {
1068                 ret = compat_calc_entry(iter, info, loc_cpu_entry, newinfo);
1069                 if (ret != 0)
1070                         return ret;
1071         }
1072         return 0;
1073 }
1074 #endif
1075
1076 static int get_info(struct net *net, void __user *user,
1077                     const int *len, int compat)
1078 {
1079         char name[XT_TABLE_MAXNAMELEN];
1080         struct xt_table *t;
1081         int ret;
1082
1083         if (*len != sizeof(struct ipt_getinfo)) {
1084                 duprintf("length %u != %zu\n", *len,
1085                          sizeof(struct ipt_getinfo));
1086                 return -EINVAL;
1087         }
1088
1089         if (copy_from_user(name, user, sizeof(name)) != 0)
1090                 return -EFAULT;
1091
1092         name[XT_TABLE_MAXNAMELEN-1] = '\0';
1093 #ifdef CONFIG_COMPAT
1094         if (compat)
1095                 xt_compat_lock(AF_INET);
1096 #endif
1097         t = try_then_request_module(xt_find_table_lock(net, AF_INET, name),
1098                                     "iptable_%s", name);
1099         if (t && !IS_ERR(t)) {
1100                 struct ipt_getinfo info;
1101                 const struct xt_table_info *private = t->private;
1102 #ifdef CONFIG_COMPAT
1103                 struct xt_table_info tmp;
1104
1105                 if (compat) {
1106                         ret = compat_table_info(private, &tmp);
1107                         xt_compat_flush_offsets(AF_INET);
1108                         private = &tmp;
1109                 }
1110 #endif
1111                 memset(&info, 0, sizeof(info));
1112                 info.valid_hooks = t->valid_hooks;
1113                 memcpy(info.hook_entry, private->hook_entry,
1114                        sizeof(info.hook_entry));
1115                 memcpy(info.underflow, private->underflow,
1116                        sizeof(info.underflow));
1117                 info.num_entries = private->number;
1118                 info.size = private->size;
1119                 strcpy(info.name, name);
1120
1121                 if (copy_to_user(user, &info, *len) != 0)
1122                         ret = -EFAULT;
1123                 else
1124                         ret = 0;
1125
1126                 xt_table_unlock(t);
1127                 module_put(t->me);
1128         } else
1129                 ret = t ? PTR_ERR(t) : -ENOENT;
1130 #ifdef CONFIG_COMPAT
1131         if (compat)
1132                 xt_compat_unlock(AF_INET);
1133 #endif
1134         return ret;
1135 }
1136
1137 static int
1138 get_entries(struct net *net, struct ipt_get_entries __user *uptr,
1139             const int *len)
1140 {
1141         int ret;
1142         struct ipt_get_entries get;
1143         struct xt_table *t;
1144
1145         if (*len < sizeof(get)) {
1146                 duprintf("get_entries: %u < %zu\n", *len, sizeof(get));
1147                 return -EINVAL;
1148         }
1149         if (copy_from_user(&get, uptr, sizeof(get)) != 0)
1150                 return -EFAULT;
1151         if (*len != sizeof(struct ipt_get_entries) + get.size) {
1152                 duprintf("get_entries: %u != %zu\n",
1153                          *len, sizeof(get) + get.size);
1154                 return -EINVAL;
1155         }
1156
1157         t = xt_find_table_lock(net, AF_INET, get.name);
1158         if (t && !IS_ERR(t)) {
1159                 const struct xt_table_info *private = t->private;
1160                 duprintf("t->private->number = %u\n", private->number);
1161                 if (get.size == private->size)
1162                         ret = copy_entries_to_user(private->size,
1163                                                    t, uptr->entrytable);
1164                 else {
1165                         duprintf("get_entries: I've got %u not %u!\n",
1166                                  private->size, get.size);
1167                         ret = -EAGAIN;
1168                 }
1169                 module_put(t->me);
1170                 xt_table_unlock(t);
1171         } else
1172                 ret = t ? PTR_ERR(t) : -ENOENT;
1173
1174         return ret;
1175 }
1176
1177 static int
1178 __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
1179              struct xt_table_info *newinfo, unsigned int num_counters,
1180              void __user *counters_ptr)
1181 {
1182         int ret;
1183         struct xt_table *t;
1184         struct xt_table_info *oldinfo;
1185         struct xt_counters *counters;
1186         void *loc_cpu_old_entry;
1187         struct ipt_entry *iter;
1188
1189         ret = 0;
1190         counters = vzalloc(num_counters * sizeof(struct xt_counters));
1191         if (!counters) {
1192                 ret = -ENOMEM;
1193                 goto out;
1194         }
1195
1196         t = try_then_request_module(xt_find_table_lock(net, AF_INET, name),
1197                                     "iptable_%s", name);
1198         if (!t || IS_ERR(t)) {
1199                 ret = t ? PTR_ERR(t) : -ENOENT;
1200                 goto free_newinfo_counters_untrans;
1201         }
1202
1203         /* You lied! */
1204         if (valid_hooks != t->valid_hooks) {
1205                 duprintf("Valid hook crap: %08X vs %08X\n",
1206                          valid_hooks, t->valid_hooks);
1207                 ret = -EINVAL;
1208                 goto put_module;
1209         }
1210
1211         oldinfo = xt_replace_table(t, num_counters, newinfo, &ret);
1212         if (!oldinfo)
1213                 goto put_module;
1214
1215         /* Update module usage count based on number of rules */
1216         duprintf("do_replace: oldnum=%u, initnum=%u, newnum=%u\n",
1217                 oldinfo->number, oldinfo->initial_entries, newinfo->number);
1218         if ((oldinfo->number > oldinfo->initial_entries) ||
1219             (newinfo->number <= oldinfo->initial_entries))
1220                 module_put(t->me);
1221         if ((oldinfo->number > oldinfo->initial_entries) &&
1222             (newinfo->number <= oldinfo->initial_entries))
1223                 module_put(t->me);
1224
1225         /* Get the old counters, and synchronize with replace */
1226         get_counters(oldinfo, counters);
1227
1228         /* Decrease module usage counts and free resource */
1229         loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()];
1230         xt_entry_foreach(iter, loc_cpu_old_entry, oldinfo->size)
1231                 cleanup_entry(iter, net);
1232
1233         xt_free_table_info(oldinfo);
1234         if (copy_to_user(counters_ptr, counters,
1235                          sizeof(struct xt_counters) * num_counters) != 0)
1236                 ret = -EFAULT;
1237         vfree(counters);
1238         xt_table_unlock(t);
1239         return ret;
1240
1241  put_module:
1242         module_put(t->me);
1243         xt_table_unlock(t);
1244  free_newinfo_counters_untrans:
1245         vfree(counters);
1246  out:
1247         return ret;
1248 }
1249
1250 static int
1251 do_replace(struct net *net, const void __user *user, unsigned int len)
1252 {
1253         int ret;
1254         struct ipt_replace tmp;
1255         struct xt_table_info *newinfo;
1256         void *loc_cpu_entry;
1257         struct ipt_entry *iter;
1258
1259         if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
1260                 return -EFAULT;
1261
1262         /* overflow check */
1263         if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
1264                 return -ENOMEM;
1265         tmp.name[sizeof(tmp.name)-1] = 0;
1266
1267         newinfo = xt_alloc_table_info(tmp.size);
1268         if (!newinfo)
1269                 return -ENOMEM;
1270
1271         /* choose the copy that is on our node/cpu */
1272         loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
1273         if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
1274                            tmp.size) != 0) {
1275                 ret = -EFAULT;
1276                 goto free_newinfo;
1277         }
1278
1279         ret = translate_table(net, newinfo, loc_cpu_entry, &tmp);
1280         if (ret != 0)
1281                 goto free_newinfo;
1282
1283         duprintf("Translated table\n");
1284
1285         ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
1286                            tmp.num_counters, tmp.counters);
1287         if (ret)
1288                 goto free_newinfo_untrans;
1289         return 0;
1290
1291  free_newinfo_untrans:
1292         xt_entry_foreach(iter, loc_cpu_entry, newinfo->size)
1293                 cleanup_entry(iter, net);
1294  free_newinfo:
1295         xt_free_table_info(newinfo);
1296         return ret;
1297 }
1298
1299 static int
1300 do_add_counters(struct net *net, const void __user *user,
1301                 unsigned int len, int compat)
1302 {
1303         unsigned int i, curcpu;
1304         struct xt_counters_info tmp;
1305         struct xt_counters *paddc;
1306         unsigned int num_counters;
1307         const char *name;
1308         int size;
1309         void *ptmp;
1310         struct xt_table *t;
1311         const struct xt_table_info *private;
1312         int ret = 0;
1313         void *loc_cpu_entry;
1314         struct ipt_entry *iter;
1315 #ifdef CONFIG_COMPAT
1316         struct compat_xt_counters_info compat_tmp;
1317
1318         if (compat) {
1319                 ptmp = &compat_tmp;
1320                 size = sizeof(struct compat_xt_counters_info);
1321         } else
1322 #endif
1323         {
1324                 ptmp = &tmp;
1325                 size = sizeof(struct xt_counters_info);
1326         }
1327
1328         if (copy_from_user(ptmp, user, size) != 0)
1329                 return -EFAULT;
1330
1331 #ifdef CONFIG_COMPAT
1332         if (compat) {
1333                 num_counters = compat_tmp.num_counters;
1334                 name = compat_tmp.name;
1335         } else
1336 #endif
1337         {
1338                 num_counters = tmp.num_counters;
1339                 name = tmp.name;
1340         }
1341
1342         if (len != size + num_counters * sizeof(struct xt_counters))
1343                 return -EINVAL;
1344
1345         paddc = vmalloc(len - size);
1346         if (!paddc)
1347                 return -ENOMEM;
1348
1349         if (copy_from_user(paddc, user + size, len - size) != 0) {
1350                 ret = -EFAULT;
1351                 goto free;
1352         }
1353
1354         t = xt_find_table_lock(net, AF_INET, name);
1355         if (!t || IS_ERR(t)) {
1356                 ret = t ? PTR_ERR(t) : -ENOENT;
1357                 goto free;
1358         }
1359
1360         local_bh_disable();
1361         private = t->private;
1362         if (private->number != num_counters) {
1363                 ret = -EINVAL;
1364                 goto unlock_up_free;
1365         }
1366
1367         i = 0;
1368         /* Choose the copy that is on our node */
1369         curcpu = smp_processor_id();
1370         loc_cpu_entry = private->entries[curcpu];
1371         xt_info_wrlock(curcpu);
1372         xt_entry_foreach(iter, loc_cpu_entry, private->size) {
1373                 ADD_COUNTER(iter->counters, paddc[i].bcnt, paddc[i].pcnt);
1374                 ++i;
1375         }
1376         xt_info_wrunlock(curcpu);
1377  unlock_up_free:
1378         local_bh_enable();
1379         xt_table_unlock(t);
1380         module_put(t->me);
1381  free:
1382         vfree(paddc);
1383
1384         return ret;
1385 }
1386
1387 #ifdef CONFIG_COMPAT
1388 struct compat_ipt_replace {
1389         char                    name[XT_TABLE_MAXNAMELEN];
1390         u32                     valid_hooks;
1391         u32                     num_entries;
1392         u32                     size;
1393         u32                     hook_entry[NF_INET_NUMHOOKS];
1394         u32                     underflow[NF_INET_NUMHOOKS];
1395         u32                     num_counters;
1396         compat_uptr_t           counters;       /* struct xt_counters * */
1397         struct compat_ipt_entry entries[0];
1398 };
1399
1400 static int
1401 compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr,
1402                           unsigned int *size, struct xt_counters *counters,
1403                           unsigned int i)
1404 {
1405         struct xt_entry_target *t;
1406         struct compat_ipt_entry __user *ce;
1407         u_int16_t target_offset, next_offset;
1408         compat_uint_t origsize;
1409         const struct xt_entry_match *ematch;
1410         int ret = 0;
1411
1412         origsize = *size;
1413         ce = (struct compat_ipt_entry __user *)*dstptr;
1414         if (copy_to_user(ce, e, sizeof(struct ipt_entry)) != 0 ||
1415             copy_to_user(&ce->counters, &counters[i],
1416             sizeof(counters[i])) != 0)
1417                 return -EFAULT;
1418
1419         *dstptr += sizeof(struct compat_ipt_entry);
1420         *size -= sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
1421
1422         xt_ematch_foreach(ematch, e) {
1423                 ret = xt_compat_match_to_user(ematch, dstptr, size);
1424                 if (ret != 0)
1425                         return ret;
1426         }
1427         target_offset = e->target_offset - (origsize - *size);
1428         t = ipt_get_target(e);
1429         ret = xt_compat_target_to_user(t, dstptr, size);
1430         if (ret)
1431                 return ret;
1432         next_offset = e->next_offset - (origsize - *size);
1433         if (put_user(target_offset, &ce->target_offset) != 0 ||
1434             put_user(next_offset, &ce->next_offset) != 0)
1435                 return -EFAULT;
1436         return 0;
1437 }
1438
1439 static int
1440 compat_find_calc_match(struct xt_entry_match *m,
1441                        const char *name,
1442                        const struct ipt_ip *ip,
1443                        unsigned int hookmask,
1444                        int *size)
1445 {
1446         struct xt_match *match;
1447
1448         match = xt_request_find_match(NFPROTO_IPV4, m->u.user.name,
1449                                       m->u.user.revision);
1450         if (IS_ERR(match)) {
1451                 duprintf("compat_check_calc_match: `%s' not found\n",
1452                          m->u.user.name);
1453                 return PTR_ERR(match);
1454         }
1455         m->u.kernel.match = match;
1456         *size += xt_compat_match_offset(match);
1457         return 0;
1458 }
1459
1460 static void compat_release_entry(struct compat_ipt_entry *e)
1461 {
1462         struct xt_entry_target *t;
1463         struct xt_entry_match *ematch;
1464
1465         /* Cleanup all matches */
1466         xt_ematch_foreach(ematch, e)
1467                 module_put(ematch->u.kernel.match->me);
1468         t = compat_ipt_get_target(e);
1469         module_put(t->u.kernel.target->me);
1470 }
1471
1472 static int
1473 check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
1474                                   struct xt_table_info *newinfo,
1475                                   unsigned int *size,
1476                                   const unsigned char *base,
1477                                   const unsigned char *limit,
1478                                   const unsigned int *hook_entries,
1479                                   const unsigned int *underflows,
1480                                   const char *name)
1481 {
1482         struct xt_entry_match *ematch;
1483         struct xt_entry_target *t;
1484         struct xt_target *target;
1485         unsigned int entry_offset;
1486         unsigned int j;
1487         int ret, off, h;
1488
1489         duprintf("check_compat_entry_size_and_hooks %p\n", e);
1490         if ((unsigned long)e % __alignof__(struct compat_ipt_entry) != 0 ||
1491             (unsigned char *)e + sizeof(struct compat_ipt_entry) >= limit) {
1492                 duprintf("Bad offset %p, limit = %p\n", e, limit);
1493                 return -EINVAL;
1494         }
1495
1496         if (e->next_offset < sizeof(struct compat_ipt_entry) +
1497                              sizeof(struct compat_xt_entry_target)) {
1498                 duprintf("checking: element %p size %u\n",
1499                          e, e->next_offset);
1500                 return -EINVAL;
1501         }
1502
1503         /* For purposes of check_entry casting the compat entry is fine */
1504         ret = check_entry((struct ipt_entry *)e, name);
1505         if (ret)
1506                 return ret;
1507
1508         off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
1509         entry_offset = (void *)e - (void *)base;
1510         j = 0;
1511         xt_ematch_foreach(ematch, e) {
1512                 ret = compat_find_calc_match(ematch, name,
1513                                              &e->ip, e->comefrom, &off);
1514                 if (ret != 0)
1515                         goto release_matches;
1516                 ++j;
1517         }
1518
1519         t = compat_ipt_get_target(e);
1520         target = xt_request_find_target(NFPROTO_IPV4, t->u.user.name,
1521                                         t->u.user.revision);
1522         if (IS_ERR(target)) {
1523                 duprintf("check_compat_entry_size_and_hooks: `%s' not found\n",
1524                          t->u.user.name);
1525                 ret = PTR_ERR(target);
1526                 goto release_matches;
1527         }
1528         t->u.kernel.target = target;
1529
1530         off += xt_compat_target_offset(target);
1531         *size += off;
1532         ret = xt_compat_add_offset(AF_INET, entry_offset, off);
1533         if (ret)
1534                 goto out;
1535
1536         /* Check hooks & underflows */
1537         for (h = 0; h < NF_INET_NUMHOOKS; h++) {
1538                 if ((unsigned char *)e - base == hook_entries[h])
1539                         newinfo->hook_entry[h] = hook_entries[h];
1540                 if ((unsigned char *)e - base == underflows[h])
1541                         newinfo->underflow[h] = underflows[h];
1542         }
1543
1544         /* Clear counters and comefrom */
1545         memset(&e->counters, 0, sizeof(e->counters));
1546         e->comefrom = 0;
1547         return 0;
1548
1549 out:
1550         module_put(t->u.kernel.target->me);
1551 release_matches:
1552         xt_ematch_foreach(ematch, e) {
1553                 if (j-- == 0)
1554                         break;
1555                 module_put(ematch->u.kernel.match->me);
1556         }
1557         return ret;
1558 }
1559
1560 static int
1561 compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
1562                             unsigned int *size, const char *name,
1563                             struct xt_table_info *newinfo, unsigned char *base)
1564 {
1565         struct xt_entry_target *t;
1566         struct xt_target *target;
1567         struct ipt_entry *de;
1568         unsigned int origsize;
1569         int ret, h;
1570         struct xt_entry_match *ematch;
1571
1572         ret = 0;
1573         origsize = *size;
1574         de = (struct ipt_entry *)*dstptr;
1575         memcpy(de, e, sizeof(struct ipt_entry));
1576         memcpy(&de->counters, &e->counters, sizeof(e->counters));
1577
1578         *dstptr += sizeof(struct ipt_entry);
1579         *size += sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
1580
1581         xt_ematch_foreach(ematch, e) {
1582                 ret = xt_compat_match_from_user(ematch, dstptr, size);
1583                 if (ret != 0)
1584                         return ret;
1585         }
1586         de->target_offset = e->target_offset - (origsize - *size);
1587         t = compat_ipt_get_target(e);
1588         target = t->u.kernel.target;
1589         xt_compat_target_from_user(t, dstptr, size);
1590
1591         de->next_offset = e->next_offset - (origsize - *size);
1592         for (h = 0; h < NF_INET_NUMHOOKS; h++) {
1593                 if ((unsigned char *)de - base < newinfo->hook_entry[h])
1594                         newinfo->hook_entry[h] -= origsize - *size;
1595                 if ((unsigned char *)de - base < newinfo->underflow[h])
1596                         newinfo->underflow[h] -= origsize - *size;
1597         }
1598         return ret;
1599 }
1600
1601 static int
1602 compat_check_entry(struct ipt_entry *e, struct net *net, const char *name)
1603 {
1604         struct xt_entry_match *ematch;
1605         struct xt_mtchk_param mtpar;
1606         unsigned int j;
1607         int ret = 0;
1608
1609         j = 0;
1610         mtpar.net       = net;
1611         mtpar.table     = name;
1612         mtpar.entryinfo = &e->ip;
1613         mtpar.hook_mask = e->comefrom;
1614         mtpar.family    = NFPROTO_IPV4;
1615         xt_ematch_foreach(ematch, e) {
1616                 ret = check_match(ematch, &mtpar);
1617                 if (ret != 0)
1618                         goto cleanup_matches;
1619                 ++j;
1620         }
1621
1622         ret = check_target(e, net, name);
1623         if (ret)
1624                 goto cleanup_matches;
1625         return 0;
1626
1627  cleanup_matches:
1628         xt_ematch_foreach(ematch, e) {
1629                 if (j-- == 0)
1630                         break;
1631                 cleanup_match(ematch, net);
1632         }
1633         return ret;
1634 }
1635
1636 static int
1637 translate_compat_table(struct net *net,
1638                        const char *name,
1639                        unsigned int valid_hooks,
1640                        struct xt_table_info **pinfo,
1641                        void **pentry0,
1642                        unsigned int total_size,
1643                        unsigned int number,
1644                        unsigned int *hook_entries,
1645                        unsigned int *underflows)
1646 {
1647         unsigned int i, j;
1648         struct xt_table_info *newinfo, *info;
1649         void *pos, *entry0, *entry1;
1650         struct compat_ipt_entry *iter0;
1651         struct ipt_entry *iter1;
1652         unsigned int size;
1653         int ret;
1654
1655         info = *pinfo;
1656         entry0 = *pentry0;
1657         size = total_size;
1658         info->number = number;
1659
1660         /* Init all hooks to impossible value. */
1661         for (i = 0; i < NF_INET_NUMHOOKS; i++) {
1662                 info->hook_entry[i] = 0xFFFFFFFF;
1663                 info->underflow[i] = 0xFFFFFFFF;
1664         }
1665
1666         duprintf("translate_compat_table: size %u\n", info->size);
1667         j = 0;
1668         xt_compat_lock(AF_INET);
1669         xt_compat_init_offsets(AF_INET, number);
1670         /* Walk through entries, checking offsets. */
1671         xt_entry_foreach(iter0, entry0, total_size) {
1672                 ret = check_compat_entry_size_and_hooks(iter0, info, &size,
1673                                                         entry0,
1674                                                         entry0 + total_size,
1675                                                         hook_entries,
1676                                                         underflows,
1677                                                         name);
1678                 if (ret != 0)
1679                         goto out_unlock;
1680                 ++j;
1681         }
1682
1683         ret = -EINVAL;
1684         if (j != number) {
1685                 duprintf("translate_compat_table: %u not %u entries\n",
1686                          j, number);
1687                 goto out_unlock;
1688         }
1689
1690         /* Check hooks all assigned */
1691         for (i = 0; i < NF_INET_NUMHOOKS; i++) {
1692                 /* Only hooks which are valid */
1693                 if (!(valid_hooks & (1 << i)))
1694                         continue;
1695                 if (info->hook_entry[i] == 0xFFFFFFFF) {
1696                         duprintf("Invalid hook entry %u %u\n",
1697                                  i, hook_entries[i]);
1698                         goto out_unlock;
1699                 }
1700                 if (info->underflow[i] == 0xFFFFFFFF) {
1701                         duprintf("Invalid underflow %u %u\n",
1702                                  i, underflows[i]);
1703                         goto out_unlock;
1704                 }
1705         }
1706
1707         ret = -ENOMEM;
1708         newinfo = xt_alloc_table_info(size);
1709         if (!newinfo)
1710                 goto out_unlock;
1711
1712         newinfo->number = number;
1713         for (i = 0; i < NF_INET_NUMHOOKS; i++) {
1714                 newinfo->hook_entry[i] = info->hook_entry[i];
1715                 newinfo->underflow[i] = info->underflow[i];
1716         }
1717         entry1 = newinfo->entries[raw_smp_processor_id()];
1718         pos = entry1;
1719         size = total_size;
1720         xt_entry_foreach(iter0, entry0, total_size) {
1721                 ret = compat_copy_entry_from_user(iter0, &pos, &size,
1722                                                   name, newinfo, entry1);
1723                 if (ret != 0)
1724                         break;
1725         }
1726         xt_compat_flush_offsets(AF_INET);
1727         xt_compat_unlock(AF_INET);
1728         if (ret)
1729                 goto free_newinfo;
1730
1731         ret = -ELOOP;
1732         if (!mark_source_chains(newinfo, valid_hooks, entry1))
1733                 goto free_newinfo;
1734
1735         i = 0;
1736         xt_entry_foreach(iter1, entry1, newinfo->size) {
1737                 ret = compat_check_entry(iter1, net, name);
1738                 if (ret != 0)
1739                         break;
1740                 ++i;
1741                 if (strcmp(ipt_get_target(iter1)->u.user.name,
1742                     XT_ERROR_TARGET) == 0)
1743                         ++newinfo->stacksize;
1744         }
1745         if (ret) {
1746                 /*
1747                  * The first i matches need cleanup_entry (calls ->destroy)
1748                  * because they had called ->check already. The other j-i
1749                  * entries need only release.
1750                  */
1751                 int skip = i;
1752                 j -= i;
1753                 xt_entry_foreach(iter0, entry0, newinfo->size) {
1754                         if (skip-- > 0)
1755                                 continue;
1756                         if (j-- == 0)
1757                                 break;
1758                         compat_release_entry(iter0);
1759                 }
1760                 xt_entry_foreach(iter1, entry1, newinfo->size) {
1761                         if (i-- == 0)
1762                                 break;
1763                         cleanup_entry(iter1, net);
1764                 }
1765                 xt_free_table_info(newinfo);
1766                 return ret;
1767         }
1768
1769         /* And one copy for every other CPU */
1770         for_each_possible_cpu(i)
1771                 if (newinfo->entries[i] && newinfo->entries[i] != entry1)
1772                         memcpy(newinfo->entries[i], entry1, newinfo->size);
1773
1774         *pinfo = newinfo;
1775         *pentry0 = entry1;
1776         xt_free_table_info(info);
1777         return 0;
1778
1779 free_newinfo:
1780         xt_free_table_info(newinfo);
1781 out:
1782         xt_entry_foreach(iter0, entry0, total_size) {
1783                 if (j-- == 0)
1784                         break;
1785                 compat_release_entry(iter0);
1786         }
1787         return ret;
1788 out_unlock:
1789         xt_compat_flush_offsets(AF_INET);
1790         xt_compat_unlock(AF_INET);
1791         goto out;
1792 }
1793
1794 static int
1795 compat_do_replace(struct net *net, void __user *user, unsigned int len)
1796 {
1797         int ret;
1798         struct compat_ipt_replace tmp;
1799         struct xt_table_info *newinfo;
1800         void *loc_cpu_entry;
1801         struct ipt_entry *iter;
1802
1803         if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
1804                 return -EFAULT;
1805
1806         /* overflow check */
1807         if (tmp.size >= INT_MAX / num_possible_cpus())
1808                 return -ENOMEM;
1809         if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
1810                 return -ENOMEM;
1811         tmp.name[sizeof(tmp.name)-1] = 0;
1812
1813         newinfo = xt_alloc_table_info(tmp.size);
1814         if (!newinfo)
1815                 return -ENOMEM;
1816
1817         /* choose the copy that is on our node/cpu */
1818         loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
1819         if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
1820                            tmp.size) != 0) {
1821                 ret = -EFAULT;
1822                 goto free_newinfo;
1823         }
1824
1825         ret = translate_compat_table(net, tmp.name, tmp.valid_hooks,
1826                                      &newinfo, &loc_cpu_entry, tmp.size,
1827                                      tmp.num_entries, tmp.hook_entry,
1828                                      tmp.underflow);
1829         if (ret != 0)
1830                 goto free_newinfo;
1831
1832         duprintf("compat_do_replace: Translated table\n");
1833
1834         ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
1835                            tmp.num_counters, compat_ptr(tmp.counters));
1836         if (ret)
1837                 goto free_newinfo_untrans;
1838         return 0;
1839
1840  free_newinfo_untrans:
1841         xt_entry_foreach(iter, loc_cpu_entry, newinfo->size)
1842                 cleanup_entry(iter, net);
1843  free_newinfo:
1844         xt_free_table_info(newinfo);
1845         return ret;
1846 }
1847
1848 static int
1849 compat_do_ipt_set_ctl(struct sock *sk,  int cmd, void __user *user,
1850                       unsigned int len)
1851 {
1852         int ret;
1853
1854         if (!capable(CAP_NET_ADMIN))
1855                 return -EPERM;
1856
1857         switch (cmd) {
1858         case IPT_SO_SET_REPLACE:
1859                 ret = compat_do_replace(sock_net(sk), user, len);
1860                 break;
1861
1862         case IPT_SO_SET_ADD_COUNTERS:
1863                 ret = do_add_counters(sock_net(sk), user, len, 1);
1864                 break;
1865
1866         default:
1867                 duprintf("do_ipt_set_ctl:  unknown request %i\n", cmd);
1868                 ret = -EINVAL;
1869         }
1870
1871         return ret;
1872 }
1873
1874 struct compat_ipt_get_entries {
1875         char name[XT_TABLE_MAXNAMELEN];
1876         compat_uint_t size;
1877         struct compat_ipt_entry entrytable[0];
1878 };
1879
1880 static int
1881 compat_copy_entries_to_user(unsigned int total_size, struct xt_table *table,
1882                             void __user *userptr)
1883 {
1884         struct xt_counters *counters;
1885         const struct xt_table_info *private = table->private;
1886         void __user *pos;
1887         unsigned int size;
1888         int ret = 0;
1889         const void *loc_cpu_entry;
1890         unsigned int i = 0;
1891         struct ipt_entry *iter;
1892
1893         counters = alloc_counters(table);
1894         if (IS_ERR(counters))
1895                 return PTR_ERR(counters);
1896
1897         /* choose the copy that is on our node/cpu, ...
1898          * This choice is lazy (because current thread is
1899          * allowed to migrate to another cpu)
1900          */
1901         loc_cpu_entry = private->entries[raw_smp_processor_id()];
1902         pos = userptr;
1903         size = total_size;
1904         xt_entry_foreach(iter, loc_cpu_entry, total_size) {
1905                 ret = compat_copy_entry_to_user(iter, &pos,
1906                                                 &size, counters, i++);
1907                 if (ret != 0)
1908                         break;
1909         }
1910
1911         vfree(counters);
1912         return ret;
1913 }
1914
1915 static int
1916 compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr,
1917                    int *len)
1918 {
1919         int ret;
1920         struct compat_ipt_get_entries get;
1921         struct xt_table *t;
1922
1923         if (*len < sizeof(get)) {
1924                 duprintf("compat_get_entries: %u < %zu\n", *len, sizeof(get));
1925                 return -EINVAL;
1926         }
1927
1928         if (copy_from_user(&get, uptr, sizeof(get)) != 0)
1929                 return -EFAULT;
1930
1931         if (*len != sizeof(struct compat_ipt_get_entries) + get.size) {
1932                 duprintf("compat_get_entries: %u != %zu\n",
1933                          *len, sizeof(get) + get.size);
1934                 return -EINVAL;
1935         }
1936
1937         xt_compat_lock(AF_INET);
1938         t = xt_find_table_lock(net, AF_INET, get.name);
1939         if (t && !IS_ERR(t)) {
1940                 const struct xt_table_info *private = t->private;
1941                 struct xt_table_info info;
1942                 duprintf("t->private->number = %u\n", private->number);
1943                 ret = compat_table_info(private, &info);
1944                 if (!ret && get.size == info.size) {
1945                         ret = compat_copy_entries_to_user(private->size,
1946                                                           t, uptr->entrytable);
1947                 } else if (!ret) {
1948                         duprintf("compat_get_entries: I've got %u not %u!\n",
1949                                  private->size, get.size);
1950                         ret = -EAGAIN;
1951                 }
1952                 xt_compat_flush_offsets(AF_INET);
1953                 module_put(t->me);
1954                 xt_table_unlock(t);
1955         } else
1956                 ret = t ? PTR_ERR(t) : -ENOENT;
1957
1958         xt_compat_unlock(AF_INET);
1959         return ret;
1960 }
1961
1962 static int do_ipt_get_ctl(struct sock *, int, void __user *, int *);
1963
1964 static int
1965 compat_do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
1966 {
1967         int ret;
1968
1969         if (!capable(CAP_NET_ADMIN))
1970                 return -EPERM;
1971
1972         switch (cmd) {
1973         case IPT_SO_GET_INFO:
1974                 ret = get_info(sock_net(sk), user, len, 1);
1975                 break;
1976         case IPT_SO_GET_ENTRIES:
1977                 ret = compat_get_entries(sock_net(sk), user, len);
1978                 break;
1979         default:
1980                 ret = do_ipt_get_ctl(sk, cmd, user, len);
1981         }
1982         return ret;
1983 }
1984 #endif
1985
1986 static int
1987 do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
1988 {
1989         int ret;
1990
1991         if (!capable(CAP_NET_ADMIN))
1992                 return -EPERM;
1993
1994         switch (cmd) {
1995         case IPT_SO_SET_REPLACE:
1996                 ret = do_replace(sock_net(sk), user, len);
1997                 break;
1998
1999         case IPT_SO_SET_ADD_COUNTERS:
2000                 ret = do_add_counters(sock_net(sk), user, len, 0);
2001                 break;
2002
2003         default:
2004                 duprintf("do_ipt_set_ctl:  unknown request %i\n", cmd);
2005                 ret = -EINVAL;
2006         }
2007
2008         return ret;
2009 }
2010
2011 static int
2012 do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
2013 {
2014         int ret;
2015
2016         if (!capable(CAP_NET_ADMIN))
2017                 return -EPERM;
2018
2019         switch (cmd) {
2020         case IPT_SO_GET_INFO:
2021                 ret = get_info(sock_net(sk), user, len, 0);
2022                 break;
2023
2024         case IPT_SO_GET_ENTRIES:
2025                 ret = get_entries(sock_net(sk), user, len);
2026                 break;
2027
2028         case IPT_SO_GET_REVISION_MATCH:
2029         case IPT_SO_GET_REVISION_TARGET: {
2030                 struct xt_get_revision rev;
2031                 int target;
2032
2033                 if (*len != sizeof(rev)) {
2034                         ret = -EINVAL;
2035                         break;
2036                 }
2037                 if (copy_from_user(&rev, user, sizeof(rev)) != 0) {
2038                         ret = -EFAULT;
2039                         break;
2040                 }
2041                 rev.name[sizeof(rev.name)-1] = 0;
2042
2043                 if (cmd == IPT_SO_GET_REVISION_TARGET)
2044                         target = 1;
2045                 else
2046                         target = 0;
2047
2048                 try_then_request_module(xt_find_revision(AF_INET, rev.name,
2049                                                          rev.revision,
2050                                                          target, &ret),
2051                                         "ipt_%s", rev.name);
2052                 break;
2053         }
2054
2055         default:
2056                 duprintf("do_ipt_get_ctl: unknown request %i\n", cmd);
2057                 ret = -EINVAL;
2058         }
2059
2060         return ret;
2061 }
2062
2063 struct xt_table *ipt_register_table(struct net *net,
2064                                     const struct xt_table *table,
2065                                     const struct ipt_replace *repl)
2066 {
2067         int ret;
2068         struct xt_table_info *newinfo;
2069         struct xt_table_info bootstrap = {0};
2070         void *loc_cpu_entry;
2071         struct xt_table *new_table;
2072
2073         newinfo = xt_alloc_table_info(repl->size);
2074         if (!newinfo) {
2075                 ret = -ENOMEM;
2076                 goto out;
2077         }
2078
2079         /* choose the copy on our node/cpu, but dont care about preemption */
2080         loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
2081         memcpy(loc_cpu_entry, repl->entries, repl->size);
2082
2083         ret = translate_table(net, newinfo, loc_cpu_entry, repl);
2084         if (ret != 0)
2085                 goto out_free;
2086
2087         new_table = xt_register_table(net, table, &bootstrap, newinfo);
2088         if (IS_ERR(new_table)) {
2089                 ret = PTR_ERR(new_table);
2090                 goto out_free;
2091         }
2092
2093         return new_table;
2094
2095 out_free:
2096         xt_free_table_info(newinfo);
2097 out:
2098         return ERR_PTR(ret);
2099 }
2100
2101 void ipt_unregister_table(struct net *net, struct xt_table *table)
2102 {
2103         struct xt_table_info *private;
2104         void *loc_cpu_entry;
2105         struct module *table_owner = table->me;
2106         struct ipt_entry *iter;
2107
2108         private = xt_unregister_table(table);
2109
2110         /* Decrease module usage counts and free resources */
2111         loc_cpu_entry = private->entries[raw_smp_processor_id()];
2112         xt_entry_foreach(iter, loc_cpu_entry, private->size)
2113                 cleanup_entry(iter, net);
2114         if (private->number > private->initial_entries)
2115                 module_put(table_owner);
2116         xt_free_table_info(private);
2117 }
2118
2119 /* Returns 1 if the type and code is matched by the range, 0 otherwise */
2120 static inline bool
2121 icmp_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code,
2122                      u_int8_t type, u_int8_t code,
2123                      bool invert)
2124 {
2125         return ((test_type == 0xFF) ||
2126                 (type == test_type && code >= min_code && code <= max_code))
2127                 ^ invert;
2128 }
2129
2130 static bool
2131 icmp_match(const struct sk_buff *skb, struct xt_action_param *par)
2132 {
2133         const struct icmphdr *ic;
2134         struct icmphdr _icmph;
2135         const struct ipt_icmp *icmpinfo = par->matchinfo;
2136
2137         /* Must not be a fragment. */
2138         if (par->fragoff != 0)
2139                 return false;
2140
2141         ic = skb_header_pointer(skb, par->thoff, sizeof(_icmph), &_icmph);
2142         if (ic == NULL) {
2143                 /* We've been asked to examine this packet, and we
2144                  * can't.  Hence, no choice but to drop.
2145                  */
2146                 duprintf("Dropping evil ICMP tinygram.\n");
2147                 par->hotdrop = true;
2148                 return false;
2149         }
2150
2151         return icmp_type_code_match(icmpinfo->type,
2152                                     icmpinfo->code[0],
2153                                     icmpinfo->code[1],
2154                                     ic->type, ic->code,
2155                                     !!(icmpinfo->invflags&IPT_ICMP_INV));
2156 }
2157
2158 static int icmp_checkentry(const struct xt_mtchk_param *par)
2159 {
2160         const struct ipt_icmp *icmpinfo = par->matchinfo;
2161
2162         /* Must specify no unknown invflags */
2163         return (icmpinfo->invflags & ~IPT_ICMP_INV) ? -EINVAL : 0;
2164 }
2165
2166 static struct xt_target ipt_builtin_tg[] __read_mostly = {
2167         {
2168                 .name             = XT_STANDARD_TARGET,
2169                 .targetsize       = sizeof(int),
2170                 .family           = NFPROTO_IPV4,
2171 #ifdef CONFIG_COMPAT
2172                 .compatsize       = sizeof(compat_int_t),
2173                 .compat_from_user = compat_standard_from_user,
2174                 .compat_to_user   = compat_standard_to_user,
2175 #endif
2176         },
2177         {
2178                 .name             = XT_ERROR_TARGET,
2179                 .target           = ipt_error,
2180                 .targetsize       = XT_FUNCTION_MAXNAMELEN,
2181                 .family           = NFPROTO_IPV4,
2182         },
2183 };
2184
2185 static struct nf_sockopt_ops ipt_sockopts = {
2186         .pf             = PF_INET,
2187         .set_optmin     = IPT_BASE_CTL,
2188         .set_optmax     = IPT_SO_SET_MAX+1,
2189         .set            = do_ipt_set_ctl,
2190 #ifdef CONFIG_COMPAT
2191         .compat_set     = compat_do_ipt_set_ctl,
2192 #endif
2193         .get_optmin     = IPT_BASE_CTL,
2194         .get_optmax     = IPT_SO_GET_MAX+1,
2195         .get            = do_ipt_get_ctl,
2196 #ifdef CONFIG_COMPAT
2197         .compat_get     = compat_do_ipt_get_ctl,
2198 #endif
2199         .owner          = THIS_MODULE,
2200 };
2201
2202 static struct xt_match ipt_builtin_mt[] __read_mostly = {
2203         {
2204                 .name       = "icmp",
2205                 .match      = icmp_match,
2206                 .matchsize  = sizeof(struct ipt_icmp),
2207                 .checkentry = icmp_checkentry,
2208                 .proto      = IPPROTO_ICMP,
2209                 .family     = NFPROTO_IPV4,
2210         },
2211 };
2212
2213 static int __net_init ip_tables_net_init(struct net *net)
2214 {
2215         return xt_proto_init(net, NFPROTO_IPV4);
2216 }
2217
2218 static void __net_exit ip_tables_net_exit(struct net *net)
2219 {
2220         xt_proto_fini(net, NFPROTO_IPV4);
2221 }
2222
2223 static struct pernet_operations ip_tables_net_ops = {
2224         .init = ip_tables_net_init,
2225         .exit = ip_tables_net_exit,
2226 };
2227
2228 static int __init ip_tables_init(void)
2229 {
2230         int ret;
2231
2232         ret = register_pernet_subsys(&ip_tables_net_ops);
2233         if (ret < 0)
2234                 goto err1;
2235
2236         /* No one else will be downing sem now, so we won't sleep */
2237         ret = xt_register_targets(ipt_builtin_tg, ARRAY_SIZE(ipt_builtin_tg));
2238         if (ret < 0)
2239                 goto err2;
2240         ret = xt_register_matches(ipt_builtin_mt, ARRAY_SIZE(ipt_builtin_mt));
2241         if (ret < 0)
2242                 goto err4;
2243
2244         /* Register setsockopt */
2245         ret = nf_register_sockopt(&ipt_sockopts);
2246         if (ret < 0)
2247                 goto err5;
2248
2249         pr_info("(C) 2000-2006 Netfilter Core Team\n");
2250         return 0;
2251
2252 err5:
2253         xt_unregister_matches(ipt_builtin_mt, ARRAY_SIZE(ipt_builtin_mt));
2254 err4:
2255         xt_unregister_targets(ipt_builtin_tg, ARRAY_SIZE(ipt_builtin_tg));
2256 err2:
2257         unregister_pernet_subsys(&ip_tables_net_ops);
2258 err1:
2259         return ret;
2260 }
2261
2262 static void __exit ip_tables_fini(void)
2263 {
2264         nf_unregister_sockopt(&ipt_sockopts);
2265
2266         xt_unregister_matches(ipt_builtin_mt, ARRAY_SIZE(ipt_builtin_mt));
2267         xt_unregister_targets(ipt_builtin_tg, ARRAY_SIZE(ipt_builtin_tg));
2268         unregister_pernet_subsys(&ip_tables_net_ops);
2269 }
2270
2271 EXPORT_SYMBOL(ipt_register_table);
2272 EXPORT_SYMBOL(ipt_unregister_table);
2273 EXPORT_SYMBOL(ipt_do_table);
2274 module_init(ip_tables_init);
2275 module_exit(ip_tables_fini);