Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: allow to turn off xtables compat layer

The compat layer needs to parse untrusted input (the ruleset)
to translate it to a 64bit compatible format.

We had a number of bugs in this department in the past, so allow users
to turn this feature off.

Add CONFIG_NETFILTER_XTABLES_COMPAT kconfig knob and make it default to y
to keep existing behaviour.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Florian Westphal and committed by
Pablo Neira Ayuso
47a6959f 50f2db9e

+70 -60
+6 -6
include/linux/netfilter/x_tables.h
··· 158 158 159 159 /* Called when entry of this type deleted. */ 160 160 void (*destroy)(const struct xt_mtdtor_param *); 161 - #ifdef CONFIG_COMPAT 161 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 162 162 /* Called when userspace align differs from kernel space one */ 163 163 void (*compat_from_user)(void *dst, const void *src); 164 164 int (*compat_to_user)(void __user *dst, const void *src); ··· 169 169 const char *table; 170 170 unsigned int matchsize; 171 171 unsigned int usersize; 172 - #ifdef CONFIG_COMPAT 172 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 173 173 unsigned int compatsize; 174 174 #endif 175 175 unsigned int hooks; ··· 199 199 200 200 /* Called when entry of this type deleted. */ 201 201 void (*destroy)(const struct xt_tgdtor_param *); 202 - #ifdef CONFIG_COMPAT 202 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 203 203 /* Called when userspace align differs from kernel space one */ 204 204 void (*compat_from_user)(void *dst, const void *src); 205 205 int (*compat_to_user)(void __user *dst, const void *src); ··· 210 210 const char *table; 211 211 unsigned int targetsize; 212 212 unsigned int usersize; 213 - #ifdef CONFIG_COMPAT 213 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 214 214 unsigned int compatsize; 215 215 #endif 216 216 unsigned int hooks; ··· 452 452 453 453 struct nf_hook_ops *xt_hook_ops_alloc(const struct xt_table *, nf_hookfn *); 454 454 455 - #ifdef CONFIG_COMPAT 455 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 456 456 #include <net/compat.h> 457 457 458 458 struct compat_xt_entry_match { ··· 533 533 unsigned int target_offset, 534 534 unsigned int next_offset); 535 535 536 - #endif /* CONFIG_COMPAT */ 536 + #endif /* CONFIG_NETFILTER_XTABLES_COMPAT */ 537 537 #endif /* _X_TABLES_H */
+1 -1
include/linux/netfilter_arp/arp_tables.h
··· 59 59 const struct nf_hook_state *state, 60 60 struct xt_table *table); 61 61 62 - #ifdef CONFIG_COMPAT 62 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 63 63 #include <net/compat.h> 64 64 65 65 struct compat_arpt_entry {
+1 -1
include/linux/netfilter_ipv4/ip_tables.h
··· 67 67 const struct nf_hook_state *state, 68 68 struct xt_table *table); 69 69 70 - #ifdef CONFIG_COMPAT 70 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 71 71 #include <net/compat.h> 72 72 73 73 struct compat_ipt_entry {
+1 -1
include/linux/netfilter_ipv6/ip6_tables.h
··· 33 33 const struct nf_hook_state *state, 34 34 struct xt_table *table); 35 35 36 - #ifdef CONFIG_COMPAT 36 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 37 37 #include <net/compat.h> 38 38 39 39 struct compat_ip6t_entry {
+2 -2
net/bridge/netfilter/ebt_limit.c
··· 87 87 } 88 88 89 89 90 - #ifdef CONFIG_COMPAT 90 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 91 91 /* 92 92 * no conversion function needed -- 93 93 * only avg/burst have meaningful values in userspace. ··· 107 107 .checkentry = ebt_limit_mt_check, 108 108 .matchsize = sizeof(struct ebt_limit_info), 109 109 .usersize = offsetof(struct ebt_limit_info, prev), 110 - #ifdef CONFIG_COMPAT 110 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 111 111 .compatsize = sizeof(struct ebt_compat_limit_info), 112 112 #endif 113 113 .me = THIS_MODULE,
+2 -2
net/bridge/netfilter/ebt_mark.c
··· 53 53 return -EINVAL; 54 54 return 0; 55 55 } 56 - #ifdef CONFIG_COMPAT 56 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 57 57 struct compat_ebt_mark_t_info { 58 58 compat_ulong_t mark; 59 59 compat_uint_t target; ··· 87 87 .target = ebt_mark_tg, 88 88 .checkentry = ebt_mark_tg_check, 89 89 .targetsize = sizeof(struct ebt_mark_t_info), 90 - #ifdef CONFIG_COMPAT 90 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 91 91 .compatsize = sizeof(struct compat_ebt_mark_t_info), 92 92 .compat_from_user = mark_tg_compat_from_user, 93 93 .compat_to_user = mark_tg_compat_to_user,
+2 -2
net/bridge/netfilter/ebt_mark_m.c
··· 37 37 } 38 38 39 39 40 - #ifdef CONFIG_COMPAT 40 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 41 41 struct compat_ebt_mark_m_info { 42 42 compat_ulong_t mark, mask; 43 43 uint8_t invert, bitmask; ··· 75 75 .match = ebt_mark_mt, 76 76 .checkentry = ebt_mark_mt_check, 77 77 .matchsize = sizeof(struct ebt_mark_m_info), 78 - #ifdef CONFIG_COMPAT 78 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 79 79 .compatsize = sizeof(struct compat_ebt_mark_m_info), 80 80 .compat_from_user = mark_mt_compat_from_user, 81 81 .compat_to_user = mark_mt_compat_to_user,
+6 -6
net/bridge/netfilter/ebtables.c
··· 47 47 static unsigned int ebt_pernet_id __read_mostly; 48 48 static DEFINE_MUTEX(ebt_mutex); 49 49 50 - #ifdef CONFIG_COMPAT 50 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 51 51 static void ebt_standard_compat_from_user(void *dst, const void *src) 52 52 { 53 53 int v = *(compat_int_t *)src; ··· 73 73 .revision = 0, 74 74 .family = NFPROTO_BRIDGE, 75 75 .targetsize = sizeof(int), 76 - #ifdef CONFIG_COMPAT 76 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 77 77 .compatsize = sizeof(compat_int_t), 78 78 .compat_from_user = ebt_standard_compat_from_user, 79 79 .compat_to_user = ebt_standard_compat_to_user, ··· 1502 1502 ebt_entry_to_user, entries, tmp.entries); 1503 1503 } 1504 1504 1505 - #ifdef CONFIG_COMPAT 1505 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 1506 1506 /* 32 bit-userspace compatibility definitions. */ 1507 1507 struct compat_ebt_replace { 1508 1508 char name[EBT_TABLE_MAXNAMELEN]; ··· 2367 2367 if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) 2368 2368 return -EPERM; 2369 2369 2370 - #ifdef CONFIG_COMPAT 2370 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 2371 2371 /* try real handler in case userland supplied needed padding */ 2372 2372 if (in_compat_syscall() && 2373 2373 ((cmd != EBT_SO_GET_INFO && cmd != EBT_SO_GET_INIT_INFO) || ··· 2434 2434 2435 2435 switch (cmd) { 2436 2436 case EBT_SO_SET_ENTRIES: 2437 - #ifdef CONFIG_COMPAT 2437 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 2438 2438 if (in_compat_syscall()) 2439 2439 ret = compat_do_replace(net, arg, len); 2440 2440 else ··· 2442 2442 ret = do_replace(net, arg, len); 2443 2443 break; 2444 2444 case EBT_SO_SET_COUNTERS: 2445 - #ifdef CONFIG_COMPAT 2445 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 2446 2446 if (in_compat_syscall()) 2447 2447 ret = compat_update_counters(net, arg, len); 2448 2448 else
+8 -8
net/ipv4/netfilter/arp_tables.c
··· 713 713 return ret; 714 714 } 715 715 716 - #ifdef CONFIG_COMPAT 716 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 717 717 static void compat_standard_from_user(void *dst, const void *src) 718 718 { 719 719 int v = *(compat_int_t *)src; ··· 800 800 return -EFAULT; 801 801 802 802 name[XT_TABLE_MAXNAMELEN-1] = '\0'; 803 - #ifdef CONFIG_COMPAT 803 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 804 804 if (in_compat_syscall()) 805 805 xt_compat_lock(NFPROTO_ARP); 806 806 #endif ··· 808 808 if (!IS_ERR(t)) { 809 809 struct arpt_getinfo info; 810 810 const struct xt_table_info *private = t->private; 811 - #ifdef CONFIG_COMPAT 811 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 812 812 struct xt_table_info tmp; 813 813 814 814 if (in_compat_syscall()) { ··· 835 835 module_put(t->me); 836 836 } else 837 837 ret = PTR_ERR(t); 838 - #ifdef CONFIG_COMPAT 838 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 839 839 if (in_compat_syscall()) 840 840 xt_compat_unlock(NFPROTO_ARP); 841 841 #endif ··· 1044 1044 return ret; 1045 1045 } 1046 1046 1047 - #ifdef CONFIG_COMPAT 1047 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 1048 1048 struct compat_arpt_replace { 1049 1049 char name[XT_TABLE_MAXNAMELEN]; 1050 1050 u32 valid_hooks; ··· 1412 1412 1413 1413 switch (cmd) { 1414 1414 case ARPT_SO_SET_REPLACE: 1415 - #ifdef CONFIG_COMPAT 1415 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 1416 1416 if (in_compat_syscall()) 1417 1417 ret = compat_do_replace(sock_net(sk), arg, len); 1418 1418 else ··· 1444 1444 break; 1445 1445 1446 1446 case ARPT_SO_GET_ENTRIES: 1447 - #ifdef CONFIG_COMPAT 1447 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 1448 1448 if (in_compat_syscall()) 1449 1449 ret = compat_get_entries(sock_net(sk), user, len); 1450 1450 else ··· 1580 1580 .name = XT_STANDARD_TARGET, 1581 1581 .targetsize = sizeof(int), 1582 1582 .family = NFPROTO_ARP, 1583 - #ifdef CONFIG_COMPAT 1583 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 1584 1584 .compatsize = sizeof(compat_int_t), 1585 1585 .compat_from_user = compat_standard_from_user, 1586 1586 .compat_to_user = compat_standard_to_user,
+8 -8
net/ipv4/netfilter/ip_tables.c
··· 868 868 return ret; 869 869 } 870 870 871 - #ifdef CONFIG_COMPAT 871 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 872 872 static void compat_standard_from_user(void *dst, const void *src) 873 873 { 874 874 int v = *(compat_int_t *)src; ··· 957 957 return -EFAULT; 958 958 959 959 name[XT_TABLE_MAXNAMELEN-1] = '\0'; 960 - #ifdef CONFIG_COMPAT 960 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 961 961 if (in_compat_syscall()) 962 962 xt_compat_lock(AF_INET); 963 963 #endif ··· 965 965 if (!IS_ERR(t)) { 966 966 struct ipt_getinfo info; 967 967 const struct xt_table_info *private = t->private; 968 - #ifdef CONFIG_COMPAT 968 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 969 969 struct xt_table_info tmp; 970 970 971 971 if (in_compat_syscall()) { ··· 993 993 module_put(t->me); 994 994 } else 995 995 ret = PTR_ERR(t); 996 - #ifdef CONFIG_COMPAT 996 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 997 997 if (in_compat_syscall()) 998 998 xt_compat_unlock(AF_INET); 999 999 #endif ··· 1199 1199 return ret; 1200 1200 } 1201 1201 1202 - #ifdef CONFIG_COMPAT 1202 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 1203 1203 struct compat_ipt_replace { 1204 1204 char name[XT_TABLE_MAXNAMELEN]; 1205 1205 u32 valid_hooks; ··· 1621 1621 1622 1622 switch (cmd) { 1623 1623 case IPT_SO_SET_REPLACE: 1624 - #ifdef CONFIG_COMPAT 1624 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 1625 1625 if (in_compat_syscall()) 1626 1626 ret = compat_do_replace(sock_net(sk), arg, len); 1627 1627 else ··· 1654 1654 break; 1655 1655 1656 1656 case IPT_SO_GET_ENTRIES: 1657 - #ifdef CONFIG_COMPAT 1657 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 1658 1658 if (in_compat_syscall()) 1659 1659 ret = compat_get_entries(sock_net(sk), user, len); 1660 1660 else ··· 1846 1846 .name = XT_STANDARD_TARGET, 1847 1847 .targetsize = sizeof(int), 1848 1848 .family = NFPROTO_IPV4, 1849 - #ifdef CONFIG_COMPAT 1849 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 1850 1850 .compatsize = sizeof(compat_int_t), 1851 1851 .compat_from_user = compat_standard_from_user, 1852 1852 .compat_to_user = compat_standard_to_user,
+4 -4
net/ipv4/netfilter/ipt_CLUSTERIP.c
··· 541 541 nf_ct_netns_put(par->net, par->family); 542 542 } 543 543 544 - #ifdef CONFIG_COMPAT 544 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 545 545 struct compat_ipt_clusterip_tgt_info 546 546 { 547 547 u_int32_t flags; ··· 553 553 u_int32_t hash_initval; 554 554 compat_uptr_t config; 555 555 }; 556 - #endif /* CONFIG_COMPAT */ 556 + #endif /* CONFIG_NETFILTER_XTABLES_COMPAT */ 557 557 558 558 static struct xt_target clusterip_tg_reg __read_mostly = { 559 559 .name = "CLUSTERIP", ··· 563 563 .destroy = clusterip_tg_destroy, 564 564 .targetsize = sizeof(struct ipt_clusterip_tgt_info), 565 565 .usersize = offsetof(struct ipt_clusterip_tgt_info, config), 566 - #ifdef CONFIG_COMPAT 566 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 567 567 .compatsize = sizeof(struct compat_ipt_clusterip_tgt_info), 568 - #endif /* CONFIG_COMPAT */ 568 + #endif /* CONFIG_NETFILTER_XTABLES_COMPAT */ 569 569 .me = THIS_MODULE 570 570 }; 571 571
+8 -8
net/ipv6/netfilter/ip6_tables.c
··· 884 884 return ret; 885 885 } 886 886 887 - #ifdef CONFIG_COMPAT 887 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 888 888 static void compat_standard_from_user(void *dst, const void *src) 889 889 { 890 890 int v = *(compat_int_t *)src; ··· 973 973 return -EFAULT; 974 974 975 975 name[XT_TABLE_MAXNAMELEN-1] = '\0'; 976 - #ifdef CONFIG_COMPAT 976 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 977 977 if (in_compat_syscall()) 978 978 xt_compat_lock(AF_INET6); 979 979 #endif ··· 981 981 if (!IS_ERR(t)) { 982 982 struct ip6t_getinfo info; 983 983 const struct xt_table_info *private = t->private; 984 - #ifdef CONFIG_COMPAT 984 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 985 985 struct xt_table_info tmp; 986 986 987 987 if (in_compat_syscall()) { ··· 1009 1009 module_put(t->me); 1010 1010 } else 1011 1011 ret = PTR_ERR(t); 1012 - #ifdef CONFIG_COMPAT 1012 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 1013 1013 if (in_compat_syscall()) 1014 1014 xt_compat_unlock(AF_INET6); 1015 1015 #endif ··· 1215 1215 return ret; 1216 1216 } 1217 1217 1218 - #ifdef CONFIG_COMPAT 1218 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 1219 1219 struct compat_ip6t_replace { 1220 1220 char name[XT_TABLE_MAXNAMELEN]; 1221 1221 u32 valid_hooks; ··· 1630 1630 1631 1631 switch (cmd) { 1632 1632 case IP6T_SO_SET_REPLACE: 1633 - #ifdef CONFIG_COMPAT 1633 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 1634 1634 if (in_compat_syscall()) 1635 1635 ret = compat_do_replace(sock_net(sk), arg, len); 1636 1636 else ··· 1663 1663 break; 1664 1664 1665 1665 case IP6T_SO_GET_ENTRIES: 1666 - #ifdef CONFIG_COMPAT 1666 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 1667 1667 if (in_compat_syscall()) 1668 1668 ret = compat_get_entries(sock_net(sk), user, len); 1669 1669 else ··· 1853 1853 .name = XT_STANDARD_TARGET, 1854 1854 .targetsize = sizeof(int), 1855 1855 .family = NFPROTO_IPV6, 1856 - #ifdef CONFIG_COMPAT 1856 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 1857 1857 .compatsize = sizeof(compat_int_t), 1858 1858 .compat_from_user = compat_standard_from_user, 1859 1859 .compat_to_user = compat_standard_to_user,
+10
net/netfilter/Kconfig
··· 728 728 729 729 if NETFILTER_XTABLES 730 730 731 + config NETFILTER_XTABLES_COMPAT 732 + bool "Netfilter Xtables 32bit support" 733 + depends on COMPAT 734 + default y 735 + help 736 + This option provides a translation layer to run 32bit arp,ip(6),ebtables 737 + binaries on 64bit kernels. 738 + 739 + If unsure, say N. 740 + 731 741 comment "Xtables combined modules" 732 742 733 743 config NETFILTER_XT_MARK
+8 -8
net/netfilter/x_tables.c
··· 52 52 struct mutex mutex; 53 53 struct list_head match; 54 54 struct list_head target; 55 - #ifdef CONFIG_COMPAT 55 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 56 56 struct mutex compat_mutex; 57 57 struct compat_delta *compat_tab; 58 58 unsigned int number; /* number of slots in compat_tab[] */ ··· 647 647 return usersize == kernsize && strnlen(msg, msglen) < msglen; 648 648 } 649 649 650 - #ifdef CONFIG_COMPAT 650 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 651 651 int xt_compat_add_offset(u_int8_t af, unsigned int offset, int delta) 652 652 { 653 653 struct xt_af *xp = &xt[af]; ··· 850 850 __alignof__(struct compat_xt_entry_match)); 851 851 } 852 852 EXPORT_SYMBOL(xt_compat_check_entry_offsets); 853 - #endif /* CONFIG_COMPAT */ 853 + #endif /* CONFIG_NETFILTER_XTABLES_COMPAT */ 854 854 855 855 /** 856 856 * xt_check_entry_offsets - validate arp/ip/ip6t_entry ··· 868 868 * match structures are aligned, and that the last structure ends where 869 869 * the target structure begins. 870 870 * 871 - * Also see xt_compat_check_entry_offsets for CONFIG_COMPAT version. 871 + * Also see xt_compat_check_entry_offsets for CONFIG_NETFILTER_XTABLES_COMPAT version. 872 872 * 873 873 * The arp/ip/ip6t_entry structure @base must have passed following tests: 874 874 * - it must point to a valid memory location ··· 1059 1059 void *mem; 1060 1060 u64 size; 1061 1061 1062 - #ifdef CONFIG_COMPAT 1062 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 1063 1063 if (in_compat_syscall()) { 1064 1064 /* structures only differ in size due to alignment */ 1065 1065 struct compat_xt_counters_info compat_tmp; ··· 1106 1106 } 1107 1107 EXPORT_SYMBOL_GPL(xt_copy_counters); 1108 1108 1109 - #ifdef CONFIG_COMPAT 1109 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 1110 1110 int xt_compat_target_offset(const struct xt_target *target) 1111 1111 { 1112 1112 u_int16_t csize = target->compatsize ? : target->targetsize; ··· 1293 1293 } 1294 1294 EXPORT_SYMBOL_GPL(xt_table_unlock); 1295 1295 1296 - #ifdef CONFIG_COMPAT 1296 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 1297 1297 void xt_compat_lock(u_int8_t af) 1298 1298 { 1299 1299 mutex_lock(&xt[af].compat_mutex); ··· 1931 1931 1932 1932 for (i = 0; i < NFPROTO_NUMPROTO; i++) { 1933 1933 mutex_init(&xt[i].mutex); 1934 - #ifdef CONFIG_COMPAT 1934 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 1935 1935 mutex_init(&xt[i].compat_mutex); 1936 1936 xt[i].compat_tab = NULL; 1937 1937 #endif
+3 -3
net/netfilter/xt_limit.c
··· 134 134 kfree(info->master); 135 135 } 136 136 137 - #ifdef CONFIG_COMPAT 137 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 138 138 struct compat_xt_rateinfo { 139 139 u_int32_t avg; 140 140 u_int32_t burst; ··· 176 176 }; 177 177 return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0; 178 178 } 179 - #endif /* CONFIG_COMPAT */ 179 + #endif /* CONFIG_NETFILTER_XTABLES_COMPAT */ 180 180 181 181 static struct xt_match limit_mt_reg __read_mostly = { 182 182 .name = "limit", ··· 186 186 .checkentry = limit_mt_check, 187 187 .destroy = limit_mt_destroy, 188 188 .matchsize = sizeof(struct xt_rateinfo), 189 - #ifdef CONFIG_COMPAT 189 + #ifdef CONFIG_NETFILTER_XTABLES_COMPAT 190 190 .compatsize = sizeof(struct compat_xt_rateinfo), 191 191 .compat_from_user = limit_mt_compat_from_user, 192 192 .compat_to_user = limit_mt_compat_to_user,