aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Engelhardt <jengelh@medozas.de>2008-10-08 05:35:20 -0400
committerPatrick McHardy <kaber@trash.net>2008-10-08 05:35:20 -0400
commit916a917dfec18535ff9e2afdafba82e6279eb4f4 (patch)
treeebd2e944684f3f1a9c184e3e69d06d1465ed2f69
parenta2df1648ba615dd5908e9a1fa7b2f133fa302487 (diff)
netfilter: xtables: provide invoked family value to extensions
By passing in the family through which extensions were invoked, a bit of data space can be reclaimed. The "family" member will be added to the parameter structures and the check functions be adjusted. Signed-off-by: Jan Engelhardt <jengelh@medozas.de> Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r--include/linux/netfilter/x_tables.h12
-rw-r--r--net/bridge/netfilter/ebtables.c11
-rw-r--r--net/ipv4/netfilter/arp_tables.c6
-rw-r--r--net/ipv4/netfilter/ip_tables.c10
-rw-r--r--net/ipv6/netfilter/ip6_tables.c10
-rw-r--r--net/netfilter/x_tables.c23
-rw-r--r--net/sched/act_ipt.c4
7 files changed, 52 insertions, 24 deletions
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index e3b3b669a143..be41b609c88f 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -183,6 +183,8 @@ struct xt_counters_info
183 * @fragoff: packet is a fragment, this is the data offset 183 * @fragoff: packet is a fragment, this is the data offset
184 * @thoff: position of transport header relative to skb->data 184 * @thoff: position of transport header relative to skb->data
185 * @hotdrop: drop packet if we had inspection problems 185 * @hotdrop: drop packet if we had inspection problems
186 * @family: Actual NFPROTO_* through which the function is invoked
187 * (helpful when match->family == NFPROTO_UNSPEC)
186 */ 188 */
187struct xt_match_param { 189struct xt_match_param {
188 const struct net_device *in, *out; 190 const struct net_device *in, *out;
@@ -191,6 +193,7 @@ struct xt_match_param {
191 int fragoff; 193 int fragoff;
192 unsigned int thoff; 194 unsigned int thoff;
193 bool *hotdrop; 195 bool *hotdrop;
196 u_int8_t family;
194}; 197};
195 198
196/** 199/**
@@ -210,12 +213,14 @@ struct xt_mtchk_param {
210 const struct xt_match *match; 213 const struct xt_match *match;
211 void *matchinfo; 214 void *matchinfo;
212 unsigned int hook_mask; 215 unsigned int hook_mask;
216 u_int8_t family;
213}; 217};
214 218
215/* Match destructor parameters */ 219/* Match destructor parameters */
216struct xt_mtdtor_param { 220struct xt_mtdtor_param {
217 const struct xt_match *match; 221 const struct xt_match *match;
218 void *matchinfo; 222 void *matchinfo;
223 u_int8_t family;
219}; 224};
220 225
221/** 226/**
@@ -232,6 +237,7 @@ struct xt_target_param {
232 unsigned int hooknum; 237 unsigned int hooknum;
233 const struct xt_target *target; 238 const struct xt_target *target;
234 const void *targinfo; 239 const void *targinfo;
240 u_int8_t family;
235}; 241};
236 242
237/** 243/**
@@ -249,12 +255,14 @@ struct xt_tgchk_param {
249 const struct xt_target *target; 255 const struct xt_target *target;
250 void *targinfo; 256 void *targinfo;
251 unsigned int hook_mask; 257 unsigned int hook_mask;
258 u_int8_t family;
252}; 259};
253 260
254/* Target destructor parameters */ 261/* Target destructor parameters */
255struct xt_tgdtor_param { 262struct xt_tgdtor_param {
256 const struct xt_target *target; 263 const struct xt_target *target;
257 void *targinfo; 264 void *targinfo;
265 u_int8_t family;
258}; 266};
259 267
260struct xt_match 268struct xt_match
@@ -393,9 +401,9 @@ extern void xt_unregister_match(struct xt_match *target);
393extern int xt_register_matches(struct xt_match *match, unsigned int n); 401extern int xt_register_matches(struct xt_match *match, unsigned int n);
394extern void xt_unregister_matches(struct xt_match *match, unsigned int n); 402extern void xt_unregister_matches(struct xt_match *match, unsigned int n);
395 403
396extern int xt_check_match(struct xt_mtchk_param *, u_int8_t family, 404extern int xt_check_match(struct xt_mtchk_param *,
397 unsigned int size, u_int8_t proto, bool inv_proto); 405 unsigned int size, u_int8_t proto, bool inv_proto);
398extern int xt_check_target(struct xt_tgchk_param *, u_int8_t family, 406extern int xt_check_target(struct xt_tgchk_param *,
399 unsigned int size, u_int8_t proto, bool inv_proto); 407 unsigned int size, u_int8_t proto, bool inv_proto);
400 408
401extern struct xt_table *xt_register_table(struct net *net, 409extern struct xt_table *xt_register_table(struct net *net,
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 29d8061fa153..5bb88eb0aad4 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -160,6 +160,7 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
160 struct xt_match_param mtpar; 160 struct xt_match_param mtpar;
161 struct xt_target_param tgpar; 161 struct xt_target_param tgpar;
162 162
163 mtpar.family = tgpar.family = NFPROTO_BRIDGE;
163 mtpar.in = tgpar.in = in; 164 mtpar.in = tgpar.in = in;
164 mtpar.out = tgpar.out = out; 165 mtpar.out = tgpar.out = out;
165 mtpar.hotdrop = &hotdrop; 166 mtpar.hotdrop = &hotdrop;
@@ -351,7 +352,7 @@ ebt_check_match(struct ebt_entry_match *m, struct xt_mtchk_param *par,
351 352
352 par->match = match; 353 par->match = match;
353 par->matchinfo = m->data; 354 par->matchinfo = m->data;
354 ret = xt_check_match(par, NFPROTO_BRIDGE, m->match_size, 355 ret = xt_check_match(par, m->match_size,
355 e->ethproto, e->invflags & EBT_IPROTO); 356 e->ethproto, e->invflags & EBT_IPROTO);
356 if (ret < 0) { 357 if (ret < 0) {
357 module_put(match->me); 358 module_put(match->me);
@@ -386,7 +387,7 @@ ebt_check_watcher(struct ebt_entry_watcher *w, struct xt_tgchk_param *par,
386 387
387 par->target = watcher; 388 par->target = watcher;
388 par->targinfo = w->data; 389 par->targinfo = w->data;
389 ret = xt_check_target(par, NFPROTO_BRIDGE, w->watcher_size, 390 ret = xt_check_target(par, w->watcher_size,
390 e->ethproto, e->invflags & EBT_IPROTO); 391 e->ethproto, e->invflags & EBT_IPROTO);
391 if (ret < 0) { 392 if (ret < 0) {
392 module_put(watcher->me); 393 module_put(watcher->me);
@@ -572,6 +573,7 @@ ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i)
572 573
573 par.match = m->u.match; 574 par.match = m->u.match;
574 par.matchinfo = m->data; 575 par.matchinfo = m->data;
576 par.family = NFPROTO_BRIDGE;
575 if (par.match->destroy != NULL) 577 if (par.match->destroy != NULL)
576 par.match->destroy(&par); 578 par.match->destroy(&par);
577 module_put(par.match->me); 579 module_put(par.match->me);
@@ -588,6 +590,7 @@ ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i)
588 590
589 par.target = w->u.watcher; 591 par.target = w->u.watcher;
590 par.targinfo = w->data; 592 par.targinfo = w->data;
593 par.family = NFPROTO_BRIDGE;
591 if (par.target->destroy != NULL) 594 if (par.target->destroy != NULL)
592 par.target->destroy(&par); 595 par.target->destroy(&par);
593 module_put(par.target->me); 596 module_put(par.target->me);
@@ -611,6 +614,7 @@ ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt)
611 614
612 par.target = t->u.target; 615 par.target = t->u.target;
613 par.targinfo = t->data; 616 par.targinfo = t->data;
617 par.family = NFPROTO_BRIDGE;
614 if (par.target->destroy != NULL) 618 if (par.target->destroy != NULL)
615 par.target->destroy(&par); 619 par.target->destroy(&par);
616 module_put(par.target->me); 620 module_put(par.target->me);
@@ -673,6 +677,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
673 mtpar.table = tgpar.table = name; 677 mtpar.table = tgpar.table = name;
674 mtpar.entryinfo = tgpar.entryinfo = e; 678 mtpar.entryinfo = tgpar.entryinfo = e;
675 mtpar.hook_mask = tgpar.hook_mask = hookmask; 679 mtpar.hook_mask = tgpar.hook_mask = hookmask;
680 mtpar.family = tgpar.family = NFPROTO_BRIDGE;
676 ret = EBT_MATCH_ITERATE(e, ebt_check_match, &mtpar, &i); 681 ret = EBT_MATCH_ITERATE(e, ebt_check_match, &mtpar, &i);
677 if (ret != 0) 682 if (ret != 0)
678 goto cleanup_matches; 683 goto cleanup_matches;
@@ -715,7 +720,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
715 720
716 tgpar.target = target; 721 tgpar.target = target;
717 tgpar.targinfo = t->data; 722 tgpar.targinfo = t->data;
718 ret = xt_check_target(&tgpar, NFPROTO_BRIDGE, t->target_size, 723 ret = xt_check_target(&tgpar, t->target_size,
719 e->ethproto, e->invflags & EBT_IPROTO); 724 e->ethproto, e->invflags & EBT_IPROTO);
720 if (ret < 0) { 725 if (ret < 0) {
721 module_put(target->me); 726 module_put(target->me);
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 3bab78330cf8..8d70d29f1ccf 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -246,6 +246,7 @@ unsigned int arpt_do_table(struct sk_buff *skb,
246 tgpar.in = in; 246 tgpar.in = in;
247 tgpar.out = out; 247 tgpar.out = out;
248 tgpar.hooknum = hook; 248 tgpar.hooknum = hook;
249 tgpar.family = NFPROTO_ARP;
249 250
250 arp = arp_hdr(skb); 251 arp = arp_hdr(skb);
251 do { 252 do {
@@ -465,10 +466,10 @@ static inline int check_target(struct arpt_entry *e, const char *name)
465 .target = t->u.kernel.target, 466 .target = t->u.kernel.target,
466 .targinfo = t->data, 467 .targinfo = t->data,
467 .hook_mask = e->comefrom, 468 .hook_mask = e->comefrom,
469 .family = NFPROTO_ARP,
468 }; 470 };
469 471
470 ret = xt_check_target(&par, NFPROTO_ARP, 472 ret = xt_check_target(&par, t->u.target_size - sizeof(*t), 0, false);
471 t->u.target_size - sizeof(*t), 0, false);
472 if (ret < 0) { 473 if (ret < 0) {
473 duprintf("arp_tables: check failed for `%s'.\n", 474 duprintf("arp_tables: check failed for `%s'.\n",
474 t->u.kernel.target->name); 475 t->u.kernel.target->name);
@@ -566,6 +567,7 @@ static inline int cleanup_entry(struct arpt_entry *e, unsigned int *i)
566 t = arpt_get_target(e); 567 t = arpt_get_target(e);
567 par.target = t->u.kernel.target; 568 par.target = t->u.kernel.target;
568 par.targinfo = t->data; 569 par.targinfo = t->data;
570 par.family = NFPROTO_ARP;
569 if (par.target->destroy != NULL) 571 if (par.target->destroy != NULL)
570 par.target->destroy(&par); 572 par.target->destroy(&par);
571 module_put(par.target->me); 573 module_put(par.target->me);
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 50b9a6c34c38..213fb27debc1 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -348,6 +348,7 @@ ipt_do_table(struct sk_buff *skb,
348 mtpar.hotdrop = &hotdrop; 348 mtpar.hotdrop = &hotdrop;
349 mtpar.in = tgpar.in = in; 349 mtpar.in = tgpar.in = in;
350 mtpar.out = tgpar.out = out; 350 mtpar.out = tgpar.out = out;
351 mtpar.family = tgpar.family = NFPROTO_IPV4;
351 tgpar.hooknum = hook; 352 tgpar.hooknum = hook;
352 353
353 read_lock_bh(&table->lock); 354 read_lock_bh(&table->lock);
@@ -579,6 +580,7 @@ cleanup_match(struct ipt_entry_match *m, unsigned int *i)
579 580
580 par.match = m->u.kernel.match; 581 par.match = m->u.kernel.match;
581 par.matchinfo = m->data; 582 par.matchinfo = m->data;
583 par.family = NFPROTO_IPV4;
582 if (par.match->destroy != NULL) 584 if (par.match->destroy != NULL)
583 par.match->destroy(&par); 585 par.match->destroy(&par);
584 module_put(par.match->me); 586 module_put(par.match->me);
@@ -616,7 +618,7 @@ check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par,
616 par->match = m->u.kernel.match; 618 par->match = m->u.kernel.match;
617 par->matchinfo = m->data; 619 par->matchinfo = m->data;
618 620
619 ret = xt_check_match(par, NFPROTO_IPV4, m->u.match_size - sizeof(*m), 621 ret = xt_check_match(par, m->u.match_size - sizeof(*m),
620 ip->proto, ip->invflags & IPT_INV_PROTO); 622 ip->proto, ip->invflags & IPT_INV_PROTO);
621 if (ret < 0) { 623 if (ret < 0) {
622 duprintf("ip_tables: check failed for `%s'.\n", 624 duprintf("ip_tables: check failed for `%s'.\n",
@@ -662,10 +664,11 @@ static int check_target(struct ipt_entry *e, const char *name)
662 .target = t->u.kernel.target, 664 .target = t->u.kernel.target,
663 .targinfo = t->data, 665 .targinfo = t->data,
664 .hook_mask = e->comefrom, 666 .hook_mask = e->comefrom,
667 .family = NFPROTO_IPV4,
665 }; 668 };
666 int ret; 669 int ret;
667 670
668 ret = xt_check_target(&par, NFPROTO_IPV4, t->u.target_size - sizeof(*t), 671 ret = xt_check_target(&par, t->u.target_size - sizeof(*t),
669 e->ip.proto, e->ip.invflags & IPT_INV_PROTO); 672 e->ip.proto, e->ip.invflags & IPT_INV_PROTO);
670 if (ret < 0) { 673 if (ret < 0) {
671 duprintf("ip_tables: check failed for `%s'.\n", 674 duprintf("ip_tables: check failed for `%s'.\n",
@@ -693,6 +696,7 @@ find_check_entry(struct ipt_entry *e, const char *name, unsigned int size,
693 mtpar.table = name; 696 mtpar.table = name;
694 mtpar.entryinfo = &e->ip; 697 mtpar.entryinfo = &e->ip;
695 mtpar.hook_mask = e->comefrom; 698 mtpar.hook_mask = e->comefrom;
699 mtpar.family = NFPROTO_IPV4;
696 ret = IPT_MATCH_ITERATE(e, find_check_match, &mtpar, &j); 700 ret = IPT_MATCH_ITERATE(e, find_check_match, &mtpar, &j);
697 if (ret != 0) 701 if (ret != 0)
698 goto cleanup_matches; 702 goto cleanup_matches;
@@ -780,6 +784,7 @@ cleanup_entry(struct ipt_entry *e, unsigned int *i)
780 784
781 par.target = t->u.kernel.target; 785 par.target = t->u.kernel.target;
782 par.targinfo = t->data; 786 par.targinfo = t->data;
787 par.family = NFPROTO_IPV4;
783 if (par.target->destroy != NULL) 788 if (par.target->destroy != NULL)
784 par.target->destroy(&par); 789 par.target->destroy(&par);
785 module_put(par.target->me); 790 module_put(par.target->me);
@@ -1659,6 +1664,7 @@ compat_check_entry(struct ipt_entry *e, const char *name,
1659 mtpar.table = name; 1664 mtpar.table = name;
1660 mtpar.entryinfo = &e->ip; 1665 mtpar.entryinfo = &e->ip;
1661 mtpar.hook_mask = e->comefrom; 1666 mtpar.hook_mask = e->comefrom;
1667 mtpar.family = NFPROTO_IPV4;
1662 ret = IPT_MATCH_ITERATE(e, check_match, &mtpar, &j); 1668 ret = IPT_MATCH_ITERATE(e, check_match, &mtpar, &j);
1663 if (ret) 1669 if (ret)
1664 goto cleanup_matches; 1670 goto cleanup_matches;
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index d934a6994632..a33485dc81cb 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -370,6 +370,7 @@ ip6t_do_table(struct sk_buff *skb,
370 mtpar.hotdrop = &hotdrop; 370 mtpar.hotdrop = &hotdrop;
371 mtpar.in = tgpar.in = in; 371 mtpar.in = tgpar.in = in;
372 mtpar.out = tgpar.out = out; 372 mtpar.out = tgpar.out = out;
373 mtpar.family = tgpar.family = NFPROTO_IPV6;
373 tgpar.hooknum = hook; 374 tgpar.hooknum = hook;
374 375
375 read_lock_bh(&table->lock); 376 read_lock_bh(&table->lock);
@@ -604,6 +605,7 @@ cleanup_match(struct ip6t_entry_match *m, unsigned int *i)
604 605
605 par.match = m->u.kernel.match; 606 par.match = m->u.kernel.match;
606 par.matchinfo = m->data; 607 par.matchinfo = m->data;
608 par.family = NFPROTO_IPV6;
607 if (par.match->destroy != NULL) 609 if (par.match->destroy != NULL)
608 par.match->destroy(&par); 610 par.match->destroy(&par);
609 module_put(par.match->me); 611 module_put(par.match->me);
@@ -640,7 +642,7 @@ static int check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par,
640 par->match = m->u.kernel.match; 642 par->match = m->u.kernel.match;
641 par->matchinfo = m->data; 643 par->matchinfo = m->data;
642 644
643 ret = xt_check_match(par, NFPROTO_IPV6, m->u.match_size - sizeof(*m), 645 ret = xt_check_match(par, m->u.match_size - sizeof(*m),
644 ipv6->proto, ipv6->invflags & IP6T_INV_PROTO); 646 ipv6->proto, ipv6->invflags & IP6T_INV_PROTO);
645 if (ret < 0) { 647 if (ret < 0) {
646 duprintf("ip_tables: check failed for `%s'.\n", 648 duprintf("ip_tables: check failed for `%s'.\n",
@@ -686,11 +688,12 @@ static int check_target(struct ip6t_entry *e, const char *name)
686 .target = t->u.kernel.target, 688 .target = t->u.kernel.target,
687 .targinfo = t->data, 689 .targinfo = t->data,
688 .hook_mask = e->comefrom, 690 .hook_mask = e->comefrom,
691 .family = NFPROTO_IPV6,
689 }; 692 };
690 int ret; 693 int ret;
691 694
692 t = ip6t_get_target(e); 695 t = ip6t_get_target(e);
693 ret = xt_check_target(&par, NFPROTO_IPV6, t->u.target_size - sizeof(*t), 696 ret = xt_check_target(&par, t->u.target_size - sizeof(*t),
694 e->ipv6.proto, e->ipv6.invflags & IP6T_INV_PROTO); 697 e->ipv6.proto, e->ipv6.invflags & IP6T_INV_PROTO);
695 if (ret < 0) { 698 if (ret < 0) {
696 duprintf("ip_tables: check failed for `%s'.\n", 699 duprintf("ip_tables: check failed for `%s'.\n",
@@ -718,6 +721,7 @@ find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
718 mtpar.table = name; 721 mtpar.table = name;
719 mtpar.entryinfo = &e->ipv6; 722 mtpar.entryinfo = &e->ipv6;
720 mtpar.hook_mask = e->comefrom; 723 mtpar.hook_mask = e->comefrom;
724 mtpar.family = NFPROTO_IPV6;
721 ret = IP6T_MATCH_ITERATE(e, find_check_match, &mtpar, &j); 725 ret = IP6T_MATCH_ITERATE(e, find_check_match, &mtpar, &j);
722 if (ret != 0) 726 if (ret != 0)
723 goto cleanup_matches; 727 goto cleanup_matches;
@@ -805,6 +809,7 @@ cleanup_entry(struct ip6t_entry *e, unsigned int *i)
805 809
806 par.target = t->u.kernel.target; 810 par.target = t->u.kernel.target;
807 par.targinfo = t->data; 811 par.targinfo = t->data;
812 par.family = NFPROTO_IPV6;
808 if (par.target->destroy != NULL) 813 if (par.target->destroy != NULL)
809 par.target->destroy(&par); 814 par.target->destroy(&par);
810 module_put(par.target->me); 815 module_put(par.target->me);
@@ -1685,6 +1690,7 @@ static int compat_check_entry(struct ip6t_entry *e, const char *name,
1685 mtpar.table = name; 1690 mtpar.table = name;
1686 mtpar.entryinfo = &e->ipv6; 1691 mtpar.entryinfo = &e->ipv6;
1687 mtpar.hook_mask = e->comefrom; 1692 mtpar.hook_mask = e->comefrom;
1693 mtpar.family = NFPROTO_IPV6;
1688 ret = IP6T_MATCH_ITERATE(e, check_match, &mtpar, &j); 1694 ret = IP6T_MATCH_ITERATE(e, check_match, &mtpar, &j);
1689 if (ret) 1695 if (ret)
1690 goto cleanup_matches; 1696 goto cleanup_matches;
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index f29513cd1399..89837a4eef76 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -321,7 +321,7 @@ int xt_find_revision(u8 af, const char *name, u8 revision, int target,
321} 321}
322EXPORT_SYMBOL_GPL(xt_find_revision); 322EXPORT_SYMBOL_GPL(xt_find_revision);
323 323
324int xt_check_match(struct xt_mtchk_param *par, u_int8_t family, 324int xt_check_match(struct xt_mtchk_param *par,
325 unsigned int size, u_int8_t proto, bool inv_proto) 325 unsigned int size, u_int8_t proto, bool inv_proto)
326{ 326{
327 if (XT_ALIGN(par->match->matchsize) != size && 327 if (XT_ALIGN(par->match->matchsize) != size &&
@@ -331,26 +331,27 @@ int xt_check_match(struct xt_mtchk_param *par, u_int8_t family,
331 * because it uses a dynamic-size data set. 331 * because it uses a dynamic-size data set.
332 */ 332 */
333 printk("%s_tables: %s match: invalid size %Zu != %u\n", 333 printk("%s_tables: %s match: invalid size %Zu != %u\n",
334 xt_prefix[family], par->match->name, 334 xt_prefix[par->family], par->match->name,
335 XT_ALIGN(par->match->matchsize), size); 335 XT_ALIGN(par->match->matchsize), size);
336 return -EINVAL; 336 return -EINVAL;
337 } 337 }
338 if (par->match->table != NULL && 338 if (par->match->table != NULL &&
339 strcmp(par->match->table, par->table) != 0) { 339 strcmp(par->match->table, par->table) != 0) {
340 printk("%s_tables: %s match: only valid in %s table, not %s\n", 340 printk("%s_tables: %s match: only valid in %s table, not %s\n",
341 xt_prefix[family], par->match->name, 341 xt_prefix[par->family], par->match->name,
342 par->match->table, par->table); 342 par->match->table, par->table);
343 return -EINVAL; 343 return -EINVAL;
344 } 344 }
345 if (par->match->hooks && (par->hook_mask & ~par->match->hooks) != 0) { 345 if (par->match->hooks && (par->hook_mask & ~par->match->hooks) != 0) {
346 printk("%s_tables: %s match: bad hook_mask %#x/%#x\n", 346 printk("%s_tables: %s match: bad hook_mask %#x/%#x\n",
347 xt_prefix[family], par->match->name, 347 xt_prefix[par->family], par->match->name,
348 par->hook_mask, par->match->hooks); 348 par->hook_mask, par->match->hooks);
349 return -EINVAL; 349 return -EINVAL;
350 } 350 }
351 if (par->match->proto && (par->match->proto != proto || inv_proto)) { 351 if (par->match->proto && (par->match->proto != proto || inv_proto)) {
352 printk("%s_tables: %s match: only valid for protocol %u\n", 352 printk("%s_tables: %s match: only valid for protocol %u\n",
353 xt_prefix[family], par->match->name, par->match->proto); 353 xt_prefix[par->family], par->match->name,
354 par->match->proto);
354 return -EINVAL; 355 return -EINVAL;
355 } 356 }
356 if (par->match->checkentry != NULL && !par->match->checkentry(par)) 357 if (par->match->checkentry != NULL && !par->match->checkentry(par))
@@ -471,31 +472,31 @@ int xt_compat_match_to_user(struct xt_entry_match *m, void __user **dstptr,
471EXPORT_SYMBOL_GPL(xt_compat_match_to_user); 472EXPORT_SYMBOL_GPL(xt_compat_match_to_user);
472#endif /* CONFIG_COMPAT */ 473#endif /* CONFIG_COMPAT */
473 474
474int xt_check_target(struct xt_tgchk_param *par, u_int8_t family, 475int xt_check_target(struct xt_tgchk_param *par,
475 unsigned int size, u_int8_t proto, bool inv_proto) 476 unsigned int size, u_int8_t proto, bool inv_proto)
476{ 477{
477 if (XT_ALIGN(par->target->targetsize) != size) { 478 if (XT_ALIGN(par->target->targetsize) != size) {
478 printk("%s_tables: %s target: invalid size %Zu != %u\n", 479 printk("%s_tables: %s target: invalid size %Zu != %u\n",
479 xt_prefix[family], par->target->name, 480 xt_prefix[par->family], par->target->name,
480 XT_ALIGN(par->target->targetsize), size); 481 XT_ALIGN(par->target->targetsize), size);
481 return -EINVAL; 482 return -EINVAL;
482 } 483 }
483 if (par->target->table != NULL && 484 if (par->target->table != NULL &&
484 strcmp(par->target->table, par->table) != 0) { 485 strcmp(par->target->table, par->table) != 0) {
485 printk("%s_tables: %s target: only valid in %s table, not %s\n", 486 printk("%s_tables: %s target: only valid in %s table, not %s\n",
486 xt_prefix[family], par->target->name, 487 xt_prefix[par->family], par->target->name,
487 par->target->table, par->table); 488 par->target->table, par->table);
488 return -EINVAL; 489 return -EINVAL;
489 } 490 }
490 if (par->target->hooks && (par->hook_mask & ~par->target->hooks) != 0) { 491 if (par->target->hooks && (par->hook_mask & ~par->target->hooks) != 0) {
491 printk("%s_tables: %s target: bad hook_mask %#x/%#x\n", 492 printk("%s_tables: %s target: bad hook_mask %#x/%#x\n",
492 xt_prefix[family], par->target->name, par->hook_mask, 493 xt_prefix[par->family], par->target->name,
493 par->target->hooks); 494 par->hook_mask, par->target->hooks);
494 return -EINVAL; 495 return -EINVAL;
495 } 496 }
496 if (par->target->proto && (par->target->proto != proto || inv_proto)) { 497 if (par->target->proto && (par->target->proto != proto || inv_proto)) {
497 printk("%s_tables: %s target: only valid for protocol %u\n", 498 printk("%s_tables: %s target: only valid for protocol %u\n",
498 xt_prefix[family], par->target->name, 499 xt_prefix[par->family], par->target->name,
499 par->target->proto); 500 par->target->proto);
500 return -EINVAL; 501 return -EINVAL;
501 } 502 }
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
index b951d422db9b..0453d79ebf57 100644
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@ -55,9 +55,9 @@ static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int
55 par.target = target; 55 par.target = target;
56 par.targinfo = t->data; 56 par.targinfo = t->data;
57 par.hook_mask = hook; 57 par.hook_mask = hook;
58 par.family = NFPROTO_IPV4;
58 59
59 ret = xt_check_target(&par, NFPROTO_IPV4, 60 ret = xt_check_target(&par, t->u.target_size - sizeof(*t), 0, false);
60 t->u.target_size - sizeof(*t), 0, false);
61 if (ret < 0) { 61 if (ret < 0) {
62 module_put(t->u.kernel.target->me); 62 module_put(t->u.kernel.target->me);
63 return ret; 63 return ret;