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