]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - net/bridge/netfilter/ebtables.c
netfilter: xtables: use "if" blocks in Kconfig
[mirror_ubuntu-hirsute-kernel.git] / net / bridge / netfilter / ebtables.c
CommitLineData
1da177e4
LT
1/*
2 * ebtables
3 *
4 * Author:
5 * Bart De Schuymer <bdschuym@pandora.be>
6 *
7 * ebtables.c,v 2.0, July, 2002
8 *
9 * This code is stongly inspired on the iptables code which is
10 * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version
15 * 2 of the License, or (at your option) any later version.
16 */
17
1da177e4
LT
18
19#include <linux/kmod.h>
20#include <linux/module.h>
21#include <linux/vmalloc.h>
18219d3f 22#include <linux/netfilter/x_tables.h>
1da177e4
LT
23#include <linux/netfilter_bridge/ebtables.h>
24#include <linux/spinlock.h>
df0933dc 25#include <linux/mutex.h>
1da177e4
LT
26#include <asm/uaccess.h>
27#include <linux/smp.h>
c8923c6b 28#include <linux/cpumask.h>
1da177e4
LT
29#include <net/sock.h>
30/* needed for logical [in,out]-dev filtering */
31#include "../br_private.h"
32
1da177e4 33#define BUGPRINT(format, args...) printk("kernel msg: ebtables bug: please "\
9d6f229f 34 "report to author: "format, ## args)
1da177e4 35/* #define BUGPRINT(format, args...) */
1da177e4 36#define MEMPRINT(format, args...) printk("kernel msg: ebtables "\
9d6f229f 37 ": out of memory: "format, ## args)
1da177e4
LT
38/* #define MEMPRINT(format, args...) */
39
40
41
42/*
43 * Each cpu has its own set of counters, so there is no need for write_lock in
44 * the softirq
45 * For reading or updating the counters, the user context needs to
46 * get a write_lock
47 */
48
49/* The size of each set of counters is altered to get cache alignment */
50#define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1))
51#define COUNTER_OFFSET(n) (SMP_ALIGN(n * sizeof(struct ebt_counter)))
52#define COUNTER_BASE(c, n, cpu) ((struct ebt_counter *)(((char *)c) + \
53 COUNTER_OFFSET(n) * cpu))
54
55
56
57b47a53 57static DEFINE_MUTEX(ebt_mutex);
1da177e4 58static LIST_HEAD(ebt_tables);
1da177e4 59
043ef46c 60static struct xt_target ebt_standard_target = {
001a18d3
JE
61 .name = "standard",
62 .revision = 0,
63 .family = NFPROTO_BRIDGE,
043ef46c 64 .targetsize = sizeof(int),
18219d3f 65};
1da177e4
LT
66
67static inline int ebt_do_watcher (struct ebt_entry_watcher *w,
2d06d4a5 68 struct sk_buff *skb, unsigned int hooknr, const struct net_device *in,
1da177e4
LT
69 const struct net_device *out)
70{
043ef46c 71 w->u.watcher->target(skb, in, out, hooknr, w->u.watcher, w->data);
1da177e4
LT
72 /* watchers don't give a verdict */
73 return 0;
74}
75
76static inline int ebt_do_match (struct ebt_entry_match *m,
77 const struct sk_buff *skb, const struct net_device *in,
5365f802 78 const struct net_device *out, bool *hotdrop)
1da177e4 79{
5365f802
JE
80 return m->u.match->match(skb, in, out, m->u.match,
81 m->data, 0, 0, hotdrop);
1da177e4
LT
82}
83
84static inline int ebt_dev_check(char *entry, const struct net_device *device)
85{
86 int i = 0;
6f5b7ef6 87 const char *devname = device->name;
1da177e4
LT
88
89 if (*entry == '\0')
90 return 0;
91 if (!device)
92 return 1;
93 /* 1 is the wildcard token */
94 while (entry[i] != '\0' && entry[i] != 1 && entry[i] == devname[i])
95 i++;
96 return (devname[i] != entry[i] && entry[i] != 1);
97}
98
99#define FWINV2(bool,invflg) ((bool) ^ !!(e->invflags & invflg))
100/* process standard matches */
101static inline int ebt_basic_match(struct ebt_entry *e, struct ethhdr *h,
102 const struct net_device *in, const struct net_device *out)
103{
104 int verdict, i;
105
106 if (e->bitmask & EBT_802_3) {
107 if (FWINV2(ntohs(h->h_proto) >= 1536, EBT_IPROTO))
108 return 1;
109 } else if (!(e->bitmask & EBT_NOPROTO) &&
110 FWINV2(e->ethproto != h->h_proto, EBT_IPROTO))
111 return 1;
112
113 if (FWINV2(ebt_dev_check(e->in, in), EBT_IIN))
114 return 1;
115 if (FWINV2(ebt_dev_check(e->out, out), EBT_IOUT))
116 return 1;
117 if ((!in || !in->br_port) ? 0 : FWINV2(ebt_dev_check(
118 e->logical_in, in->br_port->br->dev), EBT_ILOGICALIN))
119 return 1;
120 if ((!out || !out->br_port) ? 0 : FWINV2(ebt_dev_check(
121 e->logical_out, out->br_port->br->dev), EBT_ILOGICALOUT))
122 return 1;
123
124 if (e->bitmask & EBT_SOURCEMAC) {
125 verdict = 0;
126 for (i = 0; i < 6; i++)
127 verdict |= (h->h_source[i] ^ e->sourcemac[i]) &
128 e->sourcemsk[i];
129 if (FWINV2(verdict != 0, EBT_ISOURCE) )
130 return 1;
131 }
132 if (e->bitmask & EBT_DESTMAC) {
133 verdict = 0;
134 for (i = 0; i < 6; i++)
135 verdict |= (h->h_dest[i] ^ e->destmac[i]) &
136 e->destmsk[i];
137 if (FWINV2(verdict != 0, EBT_IDEST) )
138 return 1;
139 }
140 return 0;
141}
142
143/* Do some firewalling */
3db05fea 144unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
1da177e4
LT
145 const struct net_device *in, const struct net_device *out,
146 struct ebt_table *table)
147{
148 int i, nentries;
149 struct ebt_entry *point;
150 struct ebt_counter *counter_base, *cb_base;
151 struct ebt_entry_target *t;
152 int verdict, sp = 0;
153 struct ebt_chainstack *cs;
154 struct ebt_entries *chaininfo;
155 char *base;
156 struct ebt_table_info *private;
5365f802 157 bool hotdrop = false;
1da177e4
LT
158
159 read_lock_bh(&table->lock);
160 private = table->private;
161 cb_base = COUNTER_BASE(private->counters, private->nentries,
162 smp_processor_id());
163 if (private->chainstack)
164 cs = private->chainstack[smp_processor_id()];
165 else
166 cs = NULL;
167 chaininfo = private->hook_entry[hook];
168 nentries = private->hook_entry[hook]->nentries;
169 point = (struct ebt_entry *)(private->hook_entry[hook]->data);
170 counter_base = cb_base + private->hook_entry[hook]->counter_offset;
171 /* base for chain jumps */
172 base = private->entries;
173 i = 0;
174 while (i < nentries) {
3db05fea 175 if (ebt_basic_match(point, eth_hdr(skb), in, out))
1da177e4
LT
176 goto letscontinue;
177
5365f802
JE
178 if (EBT_MATCH_ITERATE(point, ebt_do_match, skb,
179 in, out, &hotdrop) != 0)
1da177e4 180 goto letscontinue;
5365f802
JE
181 if (hotdrop) {
182 read_unlock_bh(&table->lock);
183 return NF_DROP;
184 }
1da177e4
LT
185
186 /* increase counter */
187 (*(counter_base + i)).pcnt++;
3db05fea 188 (*(counter_base + i)).bcnt += skb->len;
1da177e4
LT
189
190 /* these should only watch: not modify, nor tell us
191 what to do with the packet */
3db05fea 192 EBT_WATCHER_ITERATE(point, ebt_do_watcher, skb, hook, in,
1da177e4
LT
193 out);
194
195 t = (struct ebt_entry_target *)
196 (((char *)point) + point->target_offset);
197 /* standard target */
198 if (!t->u.target->target)
199 verdict = ((struct ebt_standard_target *)t)->verdict;
200 else
2d06d4a5 201 verdict = t->u.target->target(skb, in, out, hook,
043ef46c 202 t->u.target, t->data);
1da177e4
LT
203 if (verdict == EBT_ACCEPT) {
204 read_unlock_bh(&table->lock);
205 return NF_ACCEPT;
206 }
207 if (verdict == EBT_DROP) {
208 read_unlock_bh(&table->lock);
209 return NF_DROP;
210 }
211 if (verdict == EBT_RETURN) {
212letsreturn:
213#ifdef CONFIG_NETFILTER_DEBUG
214 if (sp == 0) {
215 BUGPRINT("RETURN on base chain");
216 /* act like this is EBT_CONTINUE */
217 goto letscontinue;
218 }
219#endif
220 sp--;
221 /* put all the local variables right */
222 i = cs[sp].n;
223 chaininfo = cs[sp].chaininfo;
224 nentries = chaininfo->nentries;
225 point = cs[sp].e;
226 counter_base = cb_base +
227 chaininfo->counter_offset;
228 continue;
229 }
230 if (verdict == EBT_CONTINUE)
231 goto letscontinue;
232#ifdef CONFIG_NETFILTER_DEBUG
233 if (verdict < 0) {
234 BUGPRINT("bogus standard verdict\n");
235 read_unlock_bh(&table->lock);
236 return NF_DROP;
237 }
238#endif
239 /* jump to a udc */
240 cs[sp].n = i + 1;
241 cs[sp].chaininfo = chaininfo;
242 cs[sp].e = (struct ebt_entry *)
243 (((char *)point) + point->next_offset);
244 i = 0;
245 chaininfo = (struct ebt_entries *) (base + verdict);
246#ifdef CONFIG_NETFILTER_DEBUG
247 if (chaininfo->distinguisher) {
248 BUGPRINT("jump to non-chain\n");
249 read_unlock_bh(&table->lock);
250 return NF_DROP;
251 }
252#endif
253 nentries = chaininfo->nentries;
254 point = (struct ebt_entry *)chaininfo->data;
255 counter_base = cb_base + chaininfo->counter_offset;
256 sp++;
257 continue;
258letscontinue:
259 point = (struct ebt_entry *)
260 (((char *)point) + point->next_offset);
261 i++;
262 }
263
264 /* I actually like this :) */
265 if (chaininfo->policy == EBT_RETURN)
266 goto letsreturn;
267 if (chaininfo->policy == EBT_ACCEPT) {
268 read_unlock_bh(&table->lock);
269 return NF_ACCEPT;
270 }
271 read_unlock_bh(&table->lock);
272 return NF_DROP;
273}
274
275/* If it succeeds, returns element and locks mutex */
276static inline void *
277find_inlist_lock_noload(struct list_head *head, const char *name, int *error,
57b47a53 278 struct mutex *mutex)
1da177e4 279{
df0933dc
PM
280 struct {
281 struct list_head list;
282 char name[EBT_FUNCTION_MAXNAMELEN];
283 } *e;
1da177e4 284
57b47a53 285 *error = mutex_lock_interruptible(mutex);
1da177e4
LT
286 if (*error != 0)
287 return NULL;
288
df0933dc
PM
289 list_for_each_entry(e, head, list) {
290 if (strcmp(e->name, name) == 0)
291 return e;
1da177e4 292 }
df0933dc
PM
293 *error = -ENOENT;
294 mutex_unlock(mutex);
295 return NULL;
1da177e4
LT
296}
297
298#ifndef CONFIG_KMOD
299#define find_inlist_lock(h,n,p,e,m) find_inlist_lock_noload((h),(n),(e),(m))
300#else
301static void *
302find_inlist_lock(struct list_head *head, const char *name, const char *prefix,
57b47a53 303 int *error, struct mutex *mutex)
1da177e4
LT
304{
305 void *ret;
306
307 ret = find_inlist_lock_noload(head, name, error, mutex);
308 if (!ret) {
309 request_module("%s%s", prefix, name);
310 ret = find_inlist_lock_noload(head, name, error, mutex);
311 }
312 return ret;
313}
314#endif
315
316static inline struct ebt_table *
57b47a53 317find_table_lock(const char *name, int *error, struct mutex *mutex)
1da177e4
LT
318{
319 return find_inlist_lock(&ebt_tables, name, "ebtable_", error, mutex);
320}
321
1da177e4
LT
322static inline int
323ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e,
324 const char *name, unsigned int hookmask, unsigned int *cnt)
325{
043ef46c 326 struct xt_match *match;
14197d54 327 size_t left = ((char *)e + e->watchers_offset) - (char *)m;
1da177e4
LT
328 int ret;
329
14197d54
AV
330 if (left < sizeof(struct ebt_entry_match) ||
331 left - sizeof(struct ebt_entry_match) < m->match_size)
1da177e4 332 return -EINVAL;
043ef46c
JE
333
334 match = try_then_request_module(xt_find_match(NFPROTO_BRIDGE,
335 m->u.name, 0), "ebt_%s", m->u.name);
336 if (IS_ERR(match))
337 return PTR_ERR(match);
338 if (match == NULL)
1da177e4 339 return -ENOENT;
043ef46c
JE
340 m->u.match = match;
341
342 ret = xt_check_match(match, NFPROTO_BRIDGE, m->match_size,
367c6790
JE
343 name, hookmask, e->ethproto, e->invflags & EBT_IPROTO,
344 e, m->data);
043ef46c
JE
345 if (ret < 0) {
346 module_put(match->me);
347 return ret;
1da177e4 348 }
043ef46c 349
1da177e4
LT
350 (*cnt)++;
351 return 0;
352}
353
354static inline int
355ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e,
356 const char *name, unsigned int hookmask, unsigned int *cnt)
357{
043ef46c 358 struct xt_target *watcher;
14197d54 359 size_t left = ((char *)e + e->target_offset) - (char *)w;
1da177e4
LT
360 int ret;
361
14197d54
AV
362 if (left < sizeof(struct ebt_entry_watcher) ||
363 left - sizeof(struct ebt_entry_watcher) < w->watcher_size)
1da177e4 364 return -EINVAL;
043ef46c
JE
365
366 watcher = try_then_request_module(
367 xt_find_target(NFPROTO_BRIDGE, w->u.name, 0),
368 "ebt_%s", w->u.name);
369 if (IS_ERR(watcher))
370 return PTR_ERR(watcher);
371 if (watcher == NULL)
1da177e4 372 return -ENOENT;
043ef46c
JE
373 w->u.watcher = watcher;
374
375 ret = xt_check_target(watcher, NFPROTO_BRIDGE, w->watcher_size,
367c6790
JE
376 name, hookmask, e->ethproto, e->invflags & EBT_IPROTO,
377 e, w->data);
043ef46c
JE
378 if (ret < 0) {
379 module_put(watcher->me);
380 return ret;
1da177e4 381 }
043ef46c 382
1da177e4
LT
383 (*cnt)++;
384 return 0;
385}
386
70fe9af4
AV
387static int ebt_verify_pointers(struct ebt_replace *repl,
388 struct ebt_table_info *newinfo)
1da177e4 389{
70fe9af4
AV
390 unsigned int limit = repl->entries_size;
391 unsigned int valid_hooks = repl->valid_hooks;
392 unsigned int offset = 0;
1da177e4
LT
393 int i;
394
e4fd77de
AV
395 for (i = 0; i < NF_BR_NUMHOOKS; i++)
396 newinfo->hook_entry[i] = NULL;
397
398 newinfo->entries_size = repl->entries_size;
399 newinfo->nentries = repl->nentries;
400
70fe9af4
AV
401 while (offset < limit) {
402 size_t left = limit - offset;
403 struct ebt_entry *e = (void *)newinfo->entries + offset;
bb2ef25c 404
70fe9af4 405 if (left < sizeof(unsigned int))
1da177e4 406 break;
70fe9af4
AV
407
408 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
409 if ((valid_hooks & (1 << i)) == 0)
410 continue;
1e419cd9
AV
411 if ((char __user *)repl->hook_entry[i] ==
412 repl->entries + offset)
70fe9af4
AV
413 break;
414 }
415
416 if (i != NF_BR_NUMHOOKS || !(e->bitmask & EBT_ENTRY_OR_ENTRIES)) {
417 if (e->bitmask != 0) {
418 /* we make userspace set this right,
419 so there is no misunderstanding */
420 BUGPRINT("EBT_ENTRY_OR_ENTRIES shouldn't be set "
421 "in distinguisher\n");
422 return -EINVAL;
423 }
424 if (i != NF_BR_NUMHOOKS)
425 newinfo->hook_entry[i] = (struct ebt_entries *)e;
426 if (left < sizeof(struct ebt_entries))
427 break;
428 offset += sizeof(struct ebt_entries);
429 } else {
430 if (left < sizeof(struct ebt_entry))
431 break;
432 if (left < e->next_offset)
433 break;
434 offset += e->next_offset;
1da177e4 435 }
22b440bf 436 }
70fe9af4
AV
437 if (offset != limit) {
438 BUGPRINT("entries_size too small\n");
439 return -EINVAL;
440 }
e4fd77de
AV
441
442 /* check if all valid hooks have a chain */
443 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
444 if (!newinfo->hook_entry[i] &&
445 (valid_hooks & (1 << i))) {
446 BUGPRINT("Valid hook without chain\n");
447 return -EINVAL;
448 }
449 }
22b440bf 450 return 0;
22b440bf
AV
451}
452
453/*
454 * this one is very careful, as it is the first function
455 * to parse the userspace data
456 */
457static inline int
458ebt_check_entry_size_and_hooks(struct ebt_entry *e,
0e795531
AV
459 struct ebt_table_info *newinfo,
460 unsigned int *n, unsigned int *cnt,
461 unsigned int *totalcnt, unsigned int *udc_cnt)
22b440bf 462{
22b440bf
AV
463 int i;
464
465 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
0e795531 466 if ((void *)e == (void *)newinfo->hook_entry[i])
22b440bf
AV
467 break;
468 }
469 /* beginning of a new chain
470 if i == NF_BR_NUMHOOKS it must be a user defined chain */
471 if (i != NF_BR_NUMHOOKS || !e->bitmask) {
1da177e4
LT
472 /* this checks if the previous chain has as many entries
473 as it said it has */
474 if (*n != *cnt) {
475 BUGPRINT("nentries does not equal the nr of entries "
9d6f229f 476 "in the chain\n");
1da177e4
LT
477 return -EINVAL;
478 }
1da177e4
LT
479 if (((struct ebt_entries *)e)->policy != EBT_DROP &&
480 ((struct ebt_entries *)e)->policy != EBT_ACCEPT) {
481 /* only RETURN from udc */
482 if (i != NF_BR_NUMHOOKS ||
483 ((struct ebt_entries *)e)->policy != EBT_RETURN) {
484 BUGPRINT("bad policy\n");
485 return -EINVAL;
486 }
487 }
488 if (i == NF_BR_NUMHOOKS) /* it's a user defined chain */
489 (*udc_cnt)++;
1da177e4
LT
490 if (((struct ebt_entries *)e)->counter_offset != *totalcnt) {
491 BUGPRINT("counter_offset != totalcnt");
492 return -EINVAL;
493 }
494 *n = ((struct ebt_entries *)e)->nentries;
495 *cnt = 0;
496 return 0;
497 }
498 /* a plain old entry, heh */
499 if (sizeof(struct ebt_entry) > e->watchers_offset ||
500 e->watchers_offset > e->target_offset ||
501 e->target_offset >= e->next_offset) {
502 BUGPRINT("entry offsets not in right order\n");
503 return -EINVAL;
504 }
505 /* this is not checked anywhere else */
506 if (e->next_offset - e->target_offset < sizeof(struct ebt_entry_target)) {
507 BUGPRINT("target size too small\n");
508 return -EINVAL;
509 }
1da177e4
LT
510 (*cnt)++;
511 (*totalcnt)++;
512 return 0;
513}
514
515struct ebt_cl_stack
516{
517 struct ebt_chainstack cs;
518 int from;
519 unsigned int hookmask;
520};
521
522/*
523 * we need these positions to check that the jumps to a different part of the
524 * entries is a jump to the beginning of a new chain.
525 */
526static inline int
527ebt_get_udc_positions(struct ebt_entry *e, struct ebt_table_info *newinfo,
177abc34 528 unsigned int *n, struct ebt_cl_stack *udc)
1da177e4
LT
529{
530 int i;
531
532 /* we're only interested in chain starts */
40642f95 533 if (e->bitmask)
1da177e4
LT
534 return 0;
535 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
1da177e4
LT
536 if (newinfo->hook_entry[i] == (struct ebt_entries *)e)
537 break;
538 }
539 /* only care about udc */
540 if (i != NF_BR_NUMHOOKS)
541 return 0;
542
543 udc[*n].cs.chaininfo = (struct ebt_entries *)e;
544 /* these initialisations are depended on later in check_chainloops() */
545 udc[*n].cs.n = 0;
546 udc[*n].hookmask = 0;
547
548 (*n)++;
549 return 0;
550}
551
552static inline int
553ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i)
554{
555 if (i && (*i)-- == 0)
556 return 1;
557 if (m->u.match->destroy)
043ef46c 558 m->u.match->destroy(m->u.match, m->data);
1da177e4
LT
559 module_put(m->u.match->me);
560
561 return 0;
562}
563
564static inline int
565ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i)
566{
567 if (i && (*i)-- == 0)
568 return 1;
569 if (w->u.watcher->destroy)
043ef46c 570 w->u.watcher->destroy(w->u.watcher, w->data);
1da177e4
LT
571 module_put(w->u.watcher->me);
572
573 return 0;
574}
575
576static inline int
577ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt)
578{
579 struct ebt_entry_target *t;
580
40642f95 581 if (e->bitmask == 0)
1da177e4
LT
582 return 0;
583 /* we're done */
584 if (cnt && (*cnt)-- == 0)
585 return 1;
586 EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, NULL);
587 EBT_MATCH_ITERATE(e, ebt_cleanup_match, NULL);
588 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
589 if (t->u.target->destroy)
043ef46c 590 t->u.target->destroy(t->u.target, t->data);
1da177e4
LT
591 module_put(t->u.target->me);
592
593 return 0;
594}
595
596static inline int
597ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
f7da79d9 598 const char *name, unsigned int *cnt,
1da177e4
LT
599 struct ebt_cl_stack *cl_s, unsigned int udc_cnt)
600{
601 struct ebt_entry_target *t;
043ef46c 602 struct xt_target *target;
1da177e4 603 unsigned int i, j, hook = 0, hookmask = 0;
44f9a2fd 604 size_t gap;
1da177e4
LT
605 int ret;
606
607 /* don't mess with the struct ebt_entries */
40642f95 608 if (e->bitmask == 0)
1da177e4
LT
609 return 0;
610
611 if (e->bitmask & ~EBT_F_MASK) {
612 BUGPRINT("Unknown flag for bitmask\n");
613 return -EINVAL;
614 }
615 if (e->invflags & ~EBT_INV_MASK) {
616 BUGPRINT("Unknown flag for inv bitmask\n");
617 return -EINVAL;
618 }
619 if ( (e->bitmask & EBT_NOPROTO) && (e->bitmask & EBT_802_3) ) {
620 BUGPRINT("NOPROTO & 802_3 not allowed\n");
621 return -EINVAL;
622 }
623 /* what hook do we belong to? */
624 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
f7da79d9 625 if (!newinfo->hook_entry[i])
1da177e4
LT
626 continue;
627 if ((char *)newinfo->hook_entry[i] < (char *)e)
628 hook = i;
629 else
630 break;
631 }
632 /* (1 << NF_BR_NUMHOOKS) tells the check functions the rule is on
633 a base chain */
634 if (i < NF_BR_NUMHOOKS)
635 hookmask = (1 << hook) | (1 << NF_BR_NUMHOOKS);
636 else {
637 for (i = 0; i < udc_cnt; i++)
638 if ((char *)(cl_s[i].cs.chaininfo) > (char *)e)
639 break;
640 if (i == 0)
641 hookmask = (1 << hook) | (1 << NF_BR_NUMHOOKS);
642 else
643 hookmask = cl_s[i - 1].hookmask;
644 }
645 i = 0;
646 ret = EBT_MATCH_ITERATE(e, ebt_check_match, e, name, hookmask, &i);
647 if (ret != 0)
648 goto cleanup_matches;
649 j = 0;
650 ret = EBT_WATCHER_ITERATE(e, ebt_check_watcher, e, name, hookmask, &j);
651 if (ret != 0)
652 goto cleanup_watchers;
653 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
44f9a2fd 654 gap = e->next_offset - e->target_offset;
1da177e4 655
043ef46c
JE
656 target = try_then_request_module(
657 xt_find_target(NFPROTO_BRIDGE, t->u.name, 0),
658 "ebt_%s", t->u.name);
659 if (IS_ERR(target)) {
660 ret = PTR_ERR(target);
001a18d3 661 goto cleanup_watchers;
043ef46c
JE
662 } else if (target == NULL) {
663 ret = -ENOENT;
001a18d3
JE
664 goto cleanup_watchers;
665 }
666
1da177e4
LT
667 t->u.target = target;
668 if (t->u.target == &ebt_standard_target) {
14197d54 669 if (gap < sizeof(struct ebt_standard_target)) {
1da177e4
LT
670 BUGPRINT("Standard target size too big\n");
671 ret = -EFAULT;
672 goto cleanup_watchers;
673 }
674 if (((struct ebt_standard_target *)t)->verdict <
675 -NUM_STANDARD_TARGETS) {
676 BUGPRINT("Invalid standard target\n");
677 ret = -EFAULT;
678 goto cleanup_watchers;
679 }
18219d3f
JE
680 } else if (t->target_size > gap - sizeof(struct ebt_entry_target)) {
681 module_put(t->u.target->me);
682 ret = -EFAULT;
683 goto cleanup_watchers;
043ef46c
JE
684 }
685
686 ret = xt_check_target(target, NFPROTO_BRIDGE, t->target_size,
367c6790
JE
687 name, hookmask, e->ethproto, e->invflags & EBT_IPROTO,
688 e, t->data);
043ef46c
JE
689 if (ret < 0) {
690 module_put(target->me);
18219d3f 691 goto cleanup_watchers;
1da177e4
LT
692 }
693 (*cnt)++;
694 return 0;
695cleanup_watchers:
696 EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, &j);
697cleanup_matches:
698 EBT_MATCH_ITERATE(e, ebt_cleanup_match, &i);
699 return ret;
700}
701
702/*
703 * checks for loops and sets the hook mask for udc
704 * the hook mask for udc tells us from which base chains the udc can be
705 * accessed. This mask is a parameter to the check() functions of the extensions
706 */
707static int check_chainloops(struct ebt_entries *chain, struct ebt_cl_stack *cl_s,
708 unsigned int udc_cnt, unsigned int hooknr, char *base)
709{
710 int i, chain_nr = -1, pos = 0, nentries = chain->nentries, verdict;
711 struct ebt_entry *e = (struct ebt_entry *)chain->data;
712 struct ebt_entry_target *t;
713
714 while (pos < nentries || chain_nr != -1) {
715 /* end of udc, go back one 'recursion' step */
716 if (pos == nentries) {
717 /* put back values of the time when this chain was called */
718 e = cl_s[chain_nr].cs.e;
719 if (cl_s[chain_nr].from != -1)
720 nentries =
721 cl_s[cl_s[chain_nr].from].cs.chaininfo->nentries;
722 else
723 nentries = chain->nentries;
724 pos = cl_s[chain_nr].cs.n;
725 /* make sure we won't see a loop that isn't one */
726 cl_s[chain_nr].cs.n = 0;
727 chain_nr = cl_s[chain_nr].from;
728 if (pos == nentries)
729 continue;
730 }
731 t = (struct ebt_entry_target *)
732 (((char *)e) + e->target_offset);
733 if (strcmp(t->u.name, EBT_STANDARD_TARGET))
734 goto letscontinue;
735 if (e->target_offset + sizeof(struct ebt_standard_target) >
736 e->next_offset) {
737 BUGPRINT("Standard target size too big\n");
738 return -1;
739 }
740 verdict = ((struct ebt_standard_target *)t)->verdict;
741 if (verdict >= 0) { /* jump to another chain */
742 struct ebt_entries *hlp2 =
743 (struct ebt_entries *)(base + verdict);
744 for (i = 0; i < udc_cnt; i++)
745 if (hlp2 == cl_s[i].cs.chaininfo)
746 break;
747 /* bad destination or loop */
748 if (i == udc_cnt) {
749 BUGPRINT("bad destination\n");
750 return -1;
751 }
752 if (cl_s[i].cs.n) {
753 BUGPRINT("loop\n");
754 return -1;
755 }
98a0824a
AV
756 if (cl_s[i].hookmask & (1 << hooknr))
757 goto letscontinue;
758 /* this can't be 0, so the loop test is correct */
1da177e4
LT
759 cl_s[i].cs.n = pos + 1;
760 pos = 0;
761 cl_s[i].cs.e = ((void *)e + e->next_offset);
762 e = (struct ebt_entry *)(hlp2->data);
763 nentries = hlp2->nentries;
764 cl_s[i].from = chain_nr;
765 chain_nr = i;
766 /* this udc is accessible from the base chain for hooknr */
767 cl_s[i].hookmask |= (1 << hooknr);
768 continue;
769 }
770letscontinue:
771 e = (void *)e + e->next_offset;
772 pos++;
773 }
774 return 0;
775}
776
777/* do the parsing of the table/chains/entries/matches/watchers/targets, heh */
1bc2326c 778static int translate_table(char *name, struct ebt_table_info *newinfo)
1da177e4
LT
779{
780 unsigned int i, j, k, udc_cnt;
781 int ret;
782 struct ebt_cl_stack *cl_s = NULL; /* used in the checking for chain loops */
783
784 i = 0;
1f072c96 785 while (i < NF_BR_NUMHOOKS && !newinfo->hook_entry[i])
1da177e4
LT
786 i++;
787 if (i == NF_BR_NUMHOOKS) {
788 BUGPRINT("No valid hooks specified\n");
789 return -EINVAL;
790 }
1f072c96 791 if (newinfo->hook_entry[i] != (struct ebt_entries *)newinfo->entries) {
1da177e4
LT
792 BUGPRINT("Chains don't start at beginning\n");
793 return -EINVAL;
794 }
795 /* make sure chains are ordered after each other in same order
796 as their corresponding hooks */
797 for (j = i + 1; j < NF_BR_NUMHOOKS; j++) {
1f072c96 798 if (!newinfo->hook_entry[j])
1da177e4 799 continue;
1f072c96 800 if (newinfo->hook_entry[j] <= newinfo->hook_entry[i]) {
1da177e4
LT
801 BUGPRINT("Hook order must be followed\n");
802 return -EINVAL;
803 }
804 i = j;
805 }
806
1da177e4
LT
807 /* do some early checkings and initialize some things */
808 i = 0; /* holds the expected nr. of entries for the chain */
809 j = 0; /* holds the up to now counted entries for the chain */
810 k = 0; /* holds the total nr. of entries, should equal
9d6f229f 811 newinfo->nentries afterwards */
1da177e4
LT
812 udc_cnt = 0; /* will hold the nr. of user defined chains (udc) */
813 ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
0e795531
AV
814 ebt_check_entry_size_and_hooks, newinfo,
815 &i, &j, &k, &udc_cnt);
1da177e4
LT
816
817 if (ret != 0)
818 return ret;
819
820 if (i != j) {
821 BUGPRINT("nentries does not equal the nr of entries in the "
9d6f229f 822 "(last) chain\n");
1da177e4
LT
823 return -EINVAL;
824 }
825 if (k != newinfo->nentries) {
826 BUGPRINT("Total nentries is wrong\n");
827 return -EINVAL;
828 }
829
1da177e4
LT
830 /* get the location of the udc, put them in an array
831 while we're at it, allocate the chainstack */
832 if (udc_cnt) {
833 /* this will get free'd in do_replace()/ebt_register_table()
834 if an error occurs */
7ad4d2f6 835 newinfo->chainstack =
53b8a315 836 vmalloc(nr_cpu_ids * sizeof(*(newinfo->chainstack)));
1da177e4
LT
837 if (!newinfo->chainstack)
838 return -ENOMEM;
6f912042 839 for_each_possible_cpu(i) {
1da177e4 840 newinfo->chainstack[i] =
18bc89aa 841 vmalloc(udc_cnt * sizeof(*(newinfo->chainstack[0])));
1da177e4
LT
842 if (!newinfo->chainstack[i]) {
843 while (i)
844 vfree(newinfo->chainstack[--i]);
845 vfree(newinfo->chainstack);
846 newinfo->chainstack = NULL;
847 return -ENOMEM;
848 }
849 }
850
18bc89aa 851 cl_s = vmalloc(udc_cnt * sizeof(*cl_s));
1da177e4
LT
852 if (!cl_s)
853 return -ENOMEM;
854 i = 0; /* the i'th udc */
855 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
177abc34 856 ebt_get_udc_positions, newinfo, &i, cl_s);
1da177e4
LT
857 /* sanity check */
858 if (i != udc_cnt) {
859 BUGPRINT("i != udc_cnt\n");
860 vfree(cl_s);
861 return -EFAULT;
862 }
863 }
864
865 /* Check for loops */
866 for (i = 0; i < NF_BR_NUMHOOKS; i++)
1f072c96 867 if (newinfo->hook_entry[i])
1da177e4
LT
868 if (check_chainloops(newinfo->hook_entry[i],
869 cl_s, udc_cnt, i, newinfo->entries)) {
68d31872 870 vfree(cl_s);
1da177e4
LT
871 return -EINVAL;
872 }
873
96de0e25 874 /* we now know the following (along with E=mc²):
1da177e4
LT
875 - the nr of entries in each chain is right
876 - the size of the allocated space is right
877 - all valid hooks have a corresponding chain
878 - there are no loops
879 - wrong data can still be on the level of a single entry
880 - could be there are jumps to places that are not the
881 beginning of a chain. This can only occur in chains that
882 are not accessible from any base chains, so we don't care. */
883
884 /* used to know what we need to clean up if something goes wrong */
885 i = 0;
886 ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
1bc2326c 887 ebt_check_entry, newinfo, name, &i, cl_s, udc_cnt);
1da177e4
LT
888 if (ret != 0) {
889 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
890 ebt_cleanup_entry, &i);
891 }
68d31872 892 vfree(cl_s);
1da177e4
LT
893 return ret;
894}
895
896/* called under write_lock */
897static void get_counters(struct ebt_counter *oldcounters,
898 struct ebt_counter *counters, unsigned int nentries)
899{
900 int i, cpu;
901 struct ebt_counter *counter_base;
902
903 /* counters of cpu 0 */
904 memcpy(counters, oldcounters,
c8923c6b
DM
905 sizeof(struct ebt_counter) * nentries);
906
1da177e4 907 /* add other counters to those of cpu 0 */
6f912042 908 for_each_possible_cpu(cpu) {
c8923c6b
DM
909 if (cpu == 0)
910 continue;
1da177e4
LT
911 counter_base = COUNTER_BASE(oldcounters, nentries, cpu);
912 for (i = 0; i < nentries; i++) {
913 counters[i].pcnt += counter_base[i].pcnt;
914 counters[i].bcnt += counter_base[i].bcnt;
915 }
916 }
917}
918
919/* replace the table */
920static int do_replace(void __user *user, unsigned int len)
921{
922 int ret, i, countersize;
923 struct ebt_table_info *newinfo;
924 struct ebt_replace tmp;
925 struct ebt_table *t;
926 struct ebt_counter *counterstmp = NULL;
927 /* used to be able to unlock earlier */
928 struct ebt_table_info *table;
929
930 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
931 return -EFAULT;
932
933 if (len != sizeof(tmp) + tmp.entries_size) {
934 BUGPRINT("Wrong len argument\n");
935 return -EINVAL;
936 }
937
938 if (tmp.entries_size == 0) {
939 BUGPRINT("Entries_size never zero\n");
940 return -EINVAL;
941 }
ee4bb818
KK
942 /* overflow check */
943 if (tmp.nentries >= ((INT_MAX - sizeof(struct ebt_table_info)) / NR_CPUS -
944 SMP_CACHE_BYTES) / sizeof(struct ebt_counter))
945 return -ENOMEM;
946 if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
947 return -ENOMEM;
948
53b8a315 949 countersize = COUNTER_OFFSET(tmp.nentries) * nr_cpu_ids;
18bc89aa 950 newinfo = vmalloc(sizeof(*newinfo) + countersize);
1da177e4
LT
951 if (!newinfo)
952 return -ENOMEM;
953
954 if (countersize)
955 memset(newinfo->counters, 0, countersize);
956
8b3a7005 957 newinfo->entries = vmalloc(tmp.entries_size);
1da177e4
LT
958 if (!newinfo->entries) {
959 ret = -ENOMEM;
960 goto free_newinfo;
961 }
962 if (copy_from_user(
963 newinfo->entries, tmp.entries, tmp.entries_size) != 0) {
964 BUGPRINT("Couldn't copy entries from userspace\n");
965 ret = -EFAULT;
966 goto free_entries;
967 }
968
969 /* the user wants counters back
970 the check on the size is done later, when we have the lock */
971 if (tmp.num_counters) {
18bc89aa 972 counterstmp = vmalloc(tmp.num_counters * sizeof(*counterstmp));
1da177e4
LT
973 if (!counterstmp) {
974 ret = -ENOMEM;
975 goto free_entries;
976 }
977 }
978 else
979 counterstmp = NULL;
980
981 /* this can get initialized by translate_table() */
982 newinfo->chainstack = NULL;
1bc2326c
AV
983 ret = ebt_verify_pointers(&tmp, newinfo);
984 if (ret != 0)
985 goto free_counterstmp;
986
987 ret = translate_table(tmp.name, newinfo);
1da177e4
LT
988
989 if (ret != 0)
990 goto free_counterstmp;
991
992 t = find_table_lock(tmp.name, &ret, &ebt_mutex);
993 if (!t) {
994 ret = -ENOENT;
995 goto free_iterate;
996 }
997
998 /* the table doesn't like it */
999 if (t->check && (ret = t->check(newinfo, tmp.valid_hooks)))
1000 goto free_unlock;
1001
1002 if (tmp.num_counters && tmp.num_counters != t->private->nentries) {
1003 BUGPRINT("Wrong nr. of counters requested\n");
1004 ret = -EINVAL;
1005 goto free_unlock;
1006 }
1007
1008 /* we have the mutex lock, so no danger in reading this pointer */
1009 table = t->private;
1010 /* make sure the table can only be rmmod'ed if it contains no rules */
1011 if (!table->nentries && newinfo->nentries && !try_module_get(t->me)) {
1012 ret = -ENOENT;
1013 goto free_unlock;
1014 } else if (table->nentries && !newinfo->nentries)
1015 module_put(t->me);
1016 /* we need an atomic snapshot of the counters */
1017 write_lock_bh(&t->lock);
1018 if (tmp.num_counters)
1019 get_counters(t->private->counters, counterstmp,
1020 t->private->nentries);
1021
1022 t->private = newinfo;
1023 write_unlock_bh(&t->lock);
57b47a53 1024 mutex_unlock(&ebt_mutex);
1da177e4
LT
1025 /* so, a user can change the chains while having messed up her counter
1026 allocation. Only reason why this is done is because this way the lock
1027 is held only once, while this doesn't bring the kernel into a
1028 dangerous state. */
1029 if (tmp.num_counters &&
1030 copy_to_user(tmp.counters, counterstmp,
1031 tmp.num_counters * sizeof(struct ebt_counter))) {
1032 BUGPRINT("Couldn't copy counters to userspace\n");
1033 ret = -EFAULT;
1034 }
1035 else
1036 ret = 0;
1037
1038 /* decrease module count and free resources */
1039 EBT_ENTRY_ITERATE(table->entries, table->entries_size,
1040 ebt_cleanup_entry, NULL);
1041
1042 vfree(table->entries);
1043 if (table->chainstack) {
6f912042 1044 for_each_possible_cpu(i)
1da177e4
LT
1045 vfree(table->chainstack[i]);
1046 vfree(table->chainstack);
1047 }
1048 vfree(table);
1049
68d31872 1050 vfree(counterstmp);
1da177e4
LT
1051 return ret;
1052
1053free_unlock:
57b47a53 1054 mutex_unlock(&ebt_mutex);
1da177e4
LT
1055free_iterate:
1056 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
1057 ebt_cleanup_entry, NULL);
1058free_counterstmp:
68d31872 1059 vfree(counterstmp);
1da177e4
LT
1060 /* can be initialized in translate_table() */
1061 if (newinfo->chainstack) {
6f912042 1062 for_each_possible_cpu(i)
1da177e4
LT
1063 vfree(newinfo->chainstack[i]);
1064 vfree(newinfo->chainstack);
1065 }
1066free_entries:
68d31872 1067 vfree(newinfo->entries);
1da177e4 1068free_newinfo:
68d31872 1069 vfree(newinfo);
1da177e4
LT
1070 return ret;
1071}
1072
1da177e4
LT
1073int ebt_register_table(struct ebt_table *table)
1074{
1075 struct ebt_table_info *newinfo;
df0933dc 1076 struct ebt_table *t;
1e419cd9 1077 struct ebt_replace_kernel *repl;
1da177e4 1078 int ret, i, countersize;
df07a81e 1079 void *p;
1da177e4 1080
df07a81e
AV
1081 if (!table || !(repl = table->table) || !repl->entries ||
1082 repl->entries_size == 0 ||
1083 repl->counters || table->private) {
1da177e4
LT
1084 BUGPRINT("Bad table data for ebt_register_table!!!\n");
1085 return -EINVAL;
1086 }
1087
53b8a315 1088 countersize = COUNTER_OFFSET(repl->nentries) * nr_cpu_ids;
18bc89aa 1089 newinfo = vmalloc(sizeof(*newinfo) + countersize);
1da177e4
LT
1090 ret = -ENOMEM;
1091 if (!newinfo)
1092 return -ENOMEM;
1093
df07a81e
AV
1094 p = vmalloc(repl->entries_size);
1095 if (!p)
1da177e4
LT
1096 goto free_newinfo;
1097
df07a81e
AV
1098 memcpy(p, repl->entries, repl->entries_size);
1099 newinfo->entries = p;
1100
1101 newinfo->entries_size = repl->entries_size;
1102 newinfo->nentries = repl->nentries;
1da177e4
LT
1103
1104 if (countersize)
1105 memset(newinfo->counters, 0, countersize);
1106
1107 /* fill in newinfo and parse the entries */
1108 newinfo->chainstack = NULL;
df07a81e
AV
1109 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
1110 if ((repl->valid_hooks & (1 << i)) == 0)
1111 newinfo->hook_entry[i] = NULL;
1112 else
1113 newinfo->hook_entry[i] = p +
1114 ((char *)repl->hook_entry[i] - repl->entries);
1115 }
1116 ret = translate_table(repl->name, newinfo);
1da177e4
LT
1117 if (ret != 0) {
1118 BUGPRINT("Translate_table failed\n");
1119 goto free_chainstack;
1120 }
1121
1122 if (table->check && table->check(newinfo, table->valid_hooks)) {
1123 BUGPRINT("The table doesn't like its own initial data, lol\n");
1124 return -EINVAL;
1125 }
1126
1127 table->private = newinfo;
1128 rwlock_init(&table->lock);
57b47a53 1129 ret = mutex_lock_interruptible(&ebt_mutex);
1da177e4
LT
1130 if (ret != 0)
1131 goto free_chainstack;
1132
df0933dc
PM
1133 list_for_each_entry(t, &ebt_tables, list) {
1134 if (strcmp(t->name, table->name) == 0) {
1135 ret = -EEXIST;
1136 BUGPRINT("Table name already exists\n");
1137 goto free_unlock;
1138 }
1da177e4
LT
1139 }
1140
1141 /* Hold a reference count if the chains aren't empty */
1142 if (newinfo->nentries && !try_module_get(table->me)) {
1143 ret = -ENOENT;
1144 goto free_unlock;
1145 }
df0933dc 1146 list_add(&table->list, &ebt_tables);
57b47a53 1147 mutex_unlock(&ebt_mutex);
1da177e4
LT
1148 return 0;
1149free_unlock:
57b47a53 1150 mutex_unlock(&ebt_mutex);
1da177e4
LT
1151free_chainstack:
1152 if (newinfo->chainstack) {
6f912042 1153 for_each_possible_cpu(i)
1da177e4
LT
1154 vfree(newinfo->chainstack[i]);
1155 vfree(newinfo->chainstack);
1156 }
1157 vfree(newinfo->entries);
1158free_newinfo:
1159 vfree(newinfo);
1160 return ret;
1161}
1162
1163void ebt_unregister_table(struct ebt_table *table)
1164{
1165 int i;
1166
1167 if (!table) {
1168 BUGPRINT("Request to unregister NULL table!!!\n");
1169 return;
1170 }
57b47a53 1171 mutex_lock(&ebt_mutex);
df0933dc 1172 list_del(&table->list);
57b47a53 1173 mutex_unlock(&ebt_mutex);
68d31872 1174 vfree(table->private->entries);
1da177e4 1175 if (table->private->chainstack) {
6f912042 1176 for_each_possible_cpu(i)
1da177e4
LT
1177 vfree(table->private->chainstack[i]);
1178 vfree(table->private->chainstack);
1179 }
1180 vfree(table->private);
1181}
1182
1183/* userspace just supplied us with counters */
1184static int update_counters(void __user *user, unsigned int len)
1185{
1186 int i, ret;
1187 struct ebt_counter *tmp;
1188 struct ebt_replace hlp;
1189 struct ebt_table *t;
1190
1191 if (copy_from_user(&hlp, user, sizeof(hlp)))
1192 return -EFAULT;
1193
1194 if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter))
1195 return -EINVAL;
1196 if (hlp.num_counters == 0)
1197 return -EINVAL;
1198
18bc89aa 1199 if (!(tmp = vmalloc(hlp.num_counters * sizeof(*tmp)))) {
1da177e4
LT
1200 MEMPRINT("Update_counters && nomemory\n");
1201 return -ENOMEM;
1202 }
1203
1204 t = find_table_lock(hlp.name, &ret, &ebt_mutex);
1205 if (!t)
1206 goto free_tmp;
1207
1208 if (hlp.num_counters != t->private->nentries) {
1209 BUGPRINT("Wrong nr of counters\n");
1210 ret = -EINVAL;
1211 goto unlock_mutex;
1212 }
1213
1214 if ( copy_from_user(tmp, hlp.counters,
1215 hlp.num_counters * sizeof(struct ebt_counter)) ) {
1216 BUGPRINT("Updata_counters && !cfu\n");
1217 ret = -EFAULT;
1218 goto unlock_mutex;
1219 }
1220
1221 /* we want an atomic add of the counters */
1222 write_lock_bh(&t->lock);
1223
1224 /* we add to the counters of the first cpu */
1225 for (i = 0; i < hlp.num_counters; i++) {
1226 t->private->counters[i].pcnt += tmp[i].pcnt;
1227 t->private->counters[i].bcnt += tmp[i].bcnt;
1228 }
1229
1230 write_unlock_bh(&t->lock);
1231 ret = 0;
1232unlock_mutex:
57b47a53 1233 mutex_unlock(&ebt_mutex);
1da177e4
LT
1234free_tmp:
1235 vfree(tmp);
1236 return ret;
1237}
1238
1239static inline int ebt_make_matchname(struct ebt_entry_match *m,
1e419cd9 1240 char *base, char __user *ubase)
1da177e4 1241{
1e419cd9 1242 char __user *hlp = ubase + ((char *)m - base);
1da177e4
LT
1243 if (copy_to_user(hlp, m->u.match->name, EBT_FUNCTION_MAXNAMELEN))
1244 return -EFAULT;
1245 return 0;
1246}
1247
1248static inline int ebt_make_watchername(struct ebt_entry_watcher *w,
1e419cd9 1249 char *base, char __user *ubase)
1da177e4 1250{
1e419cd9 1251 char __user *hlp = ubase + ((char *)w - base);
1da177e4
LT
1252 if (copy_to_user(hlp , w->u.watcher->name, EBT_FUNCTION_MAXNAMELEN))
1253 return -EFAULT;
1254 return 0;
1255}
1256
1e419cd9 1257static inline int ebt_make_names(struct ebt_entry *e, char *base, char __user *ubase)
1da177e4
LT
1258{
1259 int ret;
1e419cd9 1260 char __user *hlp;
1da177e4
LT
1261 struct ebt_entry_target *t;
1262
40642f95 1263 if (e->bitmask == 0)
1da177e4
LT
1264 return 0;
1265
1e419cd9 1266 hlp = ubase + (((char *)e + e->target_offset) - base);
1da177e4 1267 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
9d6f229f 1268
1da177e4
LT
1269 ret = EBT_MATCH_ITERATE(e, ebt_make_matchname, base, ubase);
1270 if (ret != 0)
1271 return ret;
1272 ret = EBT_WATCHER_ITERATE(e, ebt_make_watchername, base, ubase);
1273 if (ret != 0)
1274 return ret;
1275 if (copy_to_user(hlp, t->u.target->name, EBT_FUNCTION_MAXNAMELEN))
1276 return -EFAULT;
1277 return 0;
1278}
1279
57b47a53 1280/* called with ebt_mutex locked */
1da177e4
LT
1281static int copy_everything_to_user(struct ebt_table *t, void __user *user,
1282 int *len, int cmd)
1283{
1284 struct ebt_replace tmp;
1285 struct ebt_counter *counterstmp, *oldcounters;
1286 unsigned int entries_size, nentries;
1287 char *entries;
1288
1289 if (cmd == EBT_SO_GET_ENTRIES) {
1290 entries_size = t->private->entries_size;
1291 nentries = t->private->nentries;
1292 entries = t->private->entries;
1293 oldcounters = t->private->counters;
1294 } else {
1295 entries_size = t->table->entries_size;
1296 nentries = t->table->nentries;
1297 entries = t->table->entries;
1298 oldcounters = t->table->counters;
1299 }
1300
1301 if (copy_from_user(&tmp, user, sizeof(tmp))) {
1302 BUGPRINT("Cfu didn't work\n");
1303 return -EFAULT;
1304 }
1305
1306 if (*len != sizeof(struct ebt_replace) + entries_size +
1307 (tmp.num_counters? nentries * sizeof(struct ebt_counter): 0)) {
1308 BUGPRINT("Wrong size\n");
1309 return -EINVAL;
1310 }
1311
1312 if (tmp.nentries != nentries) {
1313 BUGPRINT("Nentries wrong\n");
1314 return -EINVAL;
1315 }
1316
1317 if (tmp.entries_size != entries_size) {
1318 BUGPRINT("Wrong size\n");
1319 return -EINVAL;
1320 }
1321
1322 /* userspace might not need the counters */
1323 if (tmp.num_counters) {
1324 if (tmp.num_counters != nentries) {
1325 BUGPRINT("Num_counters wrong\n");
1326 return -EINVAL;
1327 }
18bc89aa 1328 counterstmp = vmalloc(nentries * sizeof(*counterstmp));
1da177e4
LT
1329 if (!counterstmp) {
1330 MEMPRINT("Couldn't copy counters, out of memory\n");
1331 return -ENOMEM;
1332 }
1333 write_lock_bh(&t->lock);
1334 get_counters(oldcounters, counterstmp, nentries);
1335 write_unlock_bh(&t->lock);
1336
1337 if (copy_to_user(tmp.counters, counterstmp,
1338 nentries * sizeof(struct ebt_counter))) {
1339 BUGPRINT("Couldn't copy counters to userspace\n");
1340 vfree(counterstmp);
1341 return -EFAULT;
1342 }
1343 vfree(counterstmp);
1344 }
1345
1346 if (copy_to_user(tmp.entries, entries, entries_size)) {
1347 BUGPRINT("Couldn't copy entries to userspace\n");
1348 return -EFAULT;
1349 }
1350 /* set the match/watcher/target names right */
1351 return EBT_ENTRY_ITERATE(entries, entries_size,
1352 ebt_make_names, entries, tmp.entries);
1353}
1354
1355static int do_ebt_set_ctl(struct sock *sk,
1356 int cmd, void __user *user, unsigned int len)
1357{
1358 int ret;
1359
1360 switch(cmd) {
1361 case EBT_SO_SET_ENTRIES:
1362 ret = do_replace(user, len);
1363 break;
1364 case EBT_SO_SET_COUNTERS:
1365 ret = update_counters(user, len);
1366 break;
1367 default:
1368 ret = -EINVAL;
1369 }
1370 return ret;
1371}
1372
1373static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
1374{
1375 int ret;
1376 struct ebt_replace tmp;
1377 struct ebt_table *t;
1378
1379 if (copy_from_user(&tmp, user, sizeof(tmp)))
1380 return -EFAULT;
1381
1382 t = find_table_lock(tmp.name, &ret, &ebt_mutex);
1383 if (!t)
1384 return ret;
1385
1386 switch(cmd) {
1387 case EBT_SO_GET_INFO:
1388 case EBT_SO_GET_INIT_INFO:
1389 if (*len != sizeof(struct ebt_replace)){
1390 ret = -EINVAL;
57b47a53 1391 mutex_unlock(&ebt_mutex);
1da177e4
LT
1392 break;
1393 }
1394 if (cmd == EBT_SO_GET_INFO) {
1395 tmp.nentries = t->private->nentries;
1396 tmp.entries_size = t->private->entries_size;
1397 tmp.valid_hooks = t->valid_hooks;
1398 } else {
1399 tmp.nentries = t->table->nentries;
1400 tmp.entries_size = t->table->entries_size;
1401 tmp.valid_hooks = t->table->valid_hooks;
1402 }
57b47a53 1403 mutex_unlock(&ebt_mutex);
1da177e4
LT
1404 if (copy_to_user(user, &tmp, *len) != 0){
1405 BUGPRINT("c2u Didn't work\n");
1406 ret = -EFAULT;
1407 break;
1408 }
1409 ret = 0;
1410 break;
1411
1412 case EBT_SO_GET_ENTRIES:
1413 case EBT_SO_GET_INIT_ENTRIES:
1414 ret = copy_everything_to_user(t, user, len, cmd);
57b47a53 1415 mutex_unlock(&ebt_mutex);
1da177e4
LT
1416 break;
1417
1418 default:
57b47a53 1419 mutex_unlock(&ebt_mutex);
1da177e4
LT
1420 ret = -EINVAL;
1421 }
1422
1423 return ret;
1424}
1425
1426static struct nf_sockopt_ops ebt_sockopts =
74ca4e5a
AM
1427{
1428 .pf = PF_INET,
1429 .set_optmin = EBT_BASE_CTL,
1430 .set_optmax = EBT_SO_SET_MAX + 1,
1431 .set = do_ebt_set_ctl,
1432 .get_optmin = EBT_BASE_CTL,
1433 .get_optmax = EBT_SO_GET_MAX + 1,
1434 .get = do_ebt_get_ctl,
16fcec35 1435 .owner = THIS_MODULE,
1da177e4
LT
1436};
1437
65b4b4e8 1438static int __init ebtables_init(void)
1da177e4
LT
1439{
1440 int ret;
1441
043ef46c
JE
1442 ret = xt_register_target(&ebt_standard_target);
1443 if (ret < 0)
1da177e4 1444 return ret;
043ef46c
JE
1445 ret = nf_register_sockopt(&ebt_sockopts);
1446 if (ret < 0) {
1447 xt_unregister_target(&ebt_standard_target);
1448 return ret;
1449 }
1da177e4 1450
a887c1c1 1451 printk(KERN_INFO "Ebtables v2.0 registered\n");
1da177e4
LT
1452 return 0;
1453}
1454
65b4b4e8 1455static void __exit ebtables_fini(void)
1da177e4
LT
1456{
1457 nf_unregister_sockopt(&ebt_sockopts);
043ef46c 1458 xt_unregister_target(&ebt_standard_target);
a887c1c1 1459 printk(KERN_INFO "Ebtables v2.0 unregistered\n");
1da177e4
LT
1460}
1461
1462EXPORT_SYMBOL(ebt_register_table);
1463EXPORT_SYMBOL(ebt_unregister_table);
1da177e4 1464EXPORT_SYMBOL(ebt_do_table);
65b4b4e8
AM
1465module_init(ebtables_init);
1466module_exit(ebtables_fini);
1da177e4 1467MODULE_LICENSE("GPL");