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>
This commit is contained in:
parent
50f2db9e36
commit
47a6959fa3
|
@ -158,7 +158,7 @@ struct xt_match {
|
||||||
|
|
||||||
/* Called when entry of this type deleted. */
|
/* Called when entry of this type deleted. */
|
||||||
void (*destroy)(const struct xt_mtdtor_param *);
|
void (*destroy)(const struct xt_mtdtor_param *);
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
/* Called when userspace align differs from kernel space one */
|
/* Called when userspace align differs from kernel space one */
|
||||||
void (*compat_from_user)(void *dst, const void *src);
|
void (*compat_from_user)(void *dst, const void *src);
|
||||||
int (*compat_to_user)(void __user *dst, const void *src);
|
int (*compat_to_user)(void __user *dst, const void *src);
|
||||||
|
@ -169,7 +169,7 @@ struct xt_match {
|
||||||
const char *table;
|
const char *table;
|
||||||
unsigned int matchsize;
|
unsigned int matchsize;
|
||||||
unsigned int usersize;
|
unsigned int usersize;
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
unsigned int compatsize;
|
unsigned int compatsize;
|
||||||
#endif
|
#endif
|
||||||
unsigned int hooks;
|
unsigned int hooks;
|
||||||
|
@ -199,7 +199,7 @@ struct xt_target {
|
||||||
|
|
||||||
/* Called when entry of this type deleted. */
|
/* Called when entry of this type deleted. */
|
||||||
void (*destroy)(const struct xt_tgdtor_param *);
|
void (*destroy)(const struct xt_tgdtor_param *);
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
/* Called when userspace align differs from kernel space one */
|
/* Called when userspace align differs from kernel space one */
|
||||||
void (*compat_from_user)(void *dst, const void *src);
|
void (*compat_from_user)(void *dst, const void *src);
|
||||||
int (*compat_to_user)(void __user *dst, const void *src);
|
int (*compat_to_user)(void __user *dst, const void *src);
|
||||||
|
@ -210,7 +210,7 @@ struct xt_target {
|
||||||
const char *table;
|
const char *table;
|
||||||
unsigned int targetsize;
|
unsigned int targetsize;
|
||||||
unsigned int usersize;
|
unsigned int usersize;
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
unsigned int compatsize;
|
unsigned int compatsize;
|
||||||
#endif
|
#endif
|
||||||
unsigned int hooks;
|
unsigned int hooks;
|
||||||
|
@ -452,7 +452,7 @@ xt_get_per_cpu_counter(struct xt_counters *cnt, unsigned int cpu)
|
||||||
|
|
||||||
struct nf_hook_ops *xt_hook_ops_alloc(const struct xt_table *, nf_hookfn *);
|
struct nf_hook_ops *xt_hook_ops_alloc(const struct xt_table *, nf_hookfn *);
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
#include <net/compat.h>
|
#include <net/compat.h>
|
||||||
|
|
||||||
struct compat_xt_entry_match {
|
struct compat_xt_entry_match {
|
||||||
|
@ -533,5 +533,5 @@ int xt_compat_check_entry_offsets(const void *base, const char *elems,
|
||||||
unsigned int target_offset,
|
unsigned int target_offset,
|
||||||
unsigned int next_offset);
|
unsigned int next_offset);
|
||||||
|
|
||||||
#endif /* CONFIG_COMPAT */
|
#endif /* CONFIG_NETFILTER_XTABLES_COMPAT */
|
||||||
#endif /* _X_TABLES_H */
|
#endif /* _X_TABLES_H */
|
||||||
|
|
|
@ -59,7 +59,7 @@ extern unsigned int arpt_do_table(struct sk_buff *skb,
|
||||||
const struct nf_hook_state *state,
|
const struct nf_hook_state *state,
|
||||||
struct xt_table *table);
|
struct xt_table *table);
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
#include <net/compat.h>
|
#include <net/compat.h>
|
||||||
|
|
||||||
struct compat_arpt_entry {
|
struct compat_arpt_entry {
|
||||||
|
|
|
@ -67,7 +67,7 @@ extern unsigned int ipt_do_table(struct sk_buff *skb,
|
||||||
const struct nf_hook_state *state,
|
const struct nf_hook_state *state,
|
||||||
struct xt_table *table);
|
struct xt_table *table);
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
#include <net/compat.h>
|
#include <net/compat.h>
|
||||||
|
|
||||||
struct compat_ipt_entry {
|
struct compat_ipt_entry {
|
||||||
|
|
|
@ -33,7 +33,7 @@ extern unsigned int ip6t_do_table(struct sk_buff *skb,
|
||||||
const struct nf_hook_state *state,
|
const struct nf_hook_state *state,
|
||||||
struct xt_table *table);
|
struct xt_table *table);
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
#include <net/compat.h>
|
#include <net/compat.h>
|
||||||
|
|
||||||
struct compat_ip6t_entry {
|
struct compat_ip6t_entry {
|
||||||
|
|
|
@ -87,7 +87,7 @@ static int ebt_limit_mt_check(const struct xt_mtchk_param *par)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
/*
|
/*
|
||||||
* no conversion function needed --
|
* no conversion function needed --
|
||||||
* only avg/burst have meaningful values in userspace.
|
* only avg/burst have meaningful values in userspace.
|
||||||
|
@ -107,7 +107,7 @@ static struct xt_match ebt_limit_mt_reg __read_mostly = {
|
||||||
.checkentry = ebt_limit_mt_check,
|
.checkentry = ebt_limit_mt_check,
|
||||||
.matchsize = sizeof(struct ebt_limit_info),
|
.matchsize = sizeof(struct ebt_limit_info),
|
||||||
.usersize = offsetof(struct ebt_limit_info, prev),
|
.usersize = offsetof(struct ebt_limit_info, prev),
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
.compatsize = sizeof(struct ebt_compat_limit_info),
|
.compatsize = sizeof(struct ebt_compat_limit_info),
|
||||||
#endif
|
#endif
|
||||||
.me = THIS_MODULE,
|
.me = THIS_MODULE,
|
||||||
|
|
|
@ -53,7 +53,7 @@ static int ebt_mark_tg_check(const struct xt_tgchk_param *par)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
struct compat_ebt_mark_t_info {
|
struct compat_ebt_mark_t_info {
|
||||||
compat_ulong_t mark;
|
compat_ulong_t mark;
|
||||||
compat_uint_t target;
|
compat_uint_t target;
|
||||||
|
@ -87,7 +87,7 @@ static struct xt_target ebt_mark_tg_reg __read_mostly = {
|
||||||
.target = ebt_mark_tg,
|
.target = ebt_mark_tg,
|
||||||
.checkentry = ebt_mark_tg_check,
|
.checkentry = ebt_mark_tg_check,
|
||||||
.targetsize = sizeof(struct ebt_mark_t_info),
|
.targetsize = sizeof(struct ebt_mark_t_info),
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
.compatsize = sizeof(struct compat_ebt_mark_t_info),
|
.compatsize = sizeof(struct compat_ebt_mark_t_info),
|
||||||
.compat_from_user = mark_tg_compat_from_user,
|
.compat_from_user = mark_tg_compat_from_user,
|
||||||
.compat_to_user = mark_tg_compat_to_user,
|
.compat_to_user = mark_tg_compat_to_user,
|
||||||
|
|
|
@ -37,7 +37,7 @@ static int ebt_mark_mt_check(const struct xt_mtchk_param *par)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
struct compat_ebt_mark_m_info {
|
struct compat_ebt_mark_m_info {
|
||||||
compat_ulong_t mark, mask;
|
compat_ulong_t mark, mask;
|
||||||
uint8_t invert, bitmask;
|
uint8_t invert, bitmask;
|
||||||
|
@ -75,7 +75,7 @@ static struct xt_match ebt_mark_mt_reg __read_mostly = {
|
||||||
.match = ebt_mark_mt,
|
.match = ebt_mark_mt,
|
||||||
.checkentry = ebt_mark_mt_check,
|
.checkentry = ebt_mark_mt_check,
|
||||||
.matchsize = sizeof(struct ebt_mark_m_info),
|
.matchsize = sizeof(struct ebt_mark_m_info),
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
.compatsize = sizeof(struct compat_ebt_mark_m_info),
|
.compatsize = sizeof(struct compat_ebt_mark_m_info),
|
||||||
.compat_from_user = mark_mt_compat_from_user,
|
.compat_from_user = mark_mt_compat_from_user,
|
||||||
.compat_to_user = mark_mt_compat_to_user,
|
.compat_to_user = mark_mt_compat_to_user,
|
||||||
|
|
|
@ -47,7 +47,7 @@ struct ebt_pernet {
|
||||||
static unsigned int ebt_pernet_id __read_mostly;
|
static unsigned int ebt_pernet_id __read_mostly;
|
||||||
static DEFINE_MUTEX(ebt_mutex);
|
static DEFINE_MUTEX(ebt_mutex);
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
static void ebt_standard_compat_from_user(void *dst, const void *src)
|
static void ebt_standard_compat_from_user(void *dst, const void *src)
|
||||||
{
|
{
|
||||||
int v = *(compat_int_t *)src;
|
int v = *(compat_int_t *)src;
|
||||||
|
@ -73,7 +73,7 @@ static struct xt_target ebt_standard_target = {
|
||||||
.revision = 0,
|
.revision = 0,
|
||||||
.family = NFPROTO_BRIDGE,
|
.family = NFPROTO_BRIDGE,
|
||||||
.targetsize = sizeof(int),
|
.targetsize = sizeof(int),
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
.compatsize = sizeof(compat_int_t),
|
.compatsize = sizeof(compat_int_t),
|
||||||
.compat_from_user = ebt_standard_compat_from_user,
|
.compat_from_user = ebt_standard_compat_from_user,
|
||||||
.compat_to_user = ebt_standard_compat_to_user,
|
.compat_to_user = ebt_standard_compat_to_user,
|
||||||
|
@ -1502,7 +1502,7 @@ static int copy_everything_to_user(struct ebt_table *t, void __user *user,
|
||||||
ebt_entry_to_user, entries, tmp.entries);
|
ebt_entry_to_user, entries, tmp.entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
/* 32 bit-userspace compatibility definitions. */
|
/* 32 bit-userspace compatibility definitions. */
|
||||||
struct compat_ebt_replace {
|
struct compat_ebt_replace {
|
||||||
char name[EBT_TABLE_MAXNAMELEN];
|
char name[EBT_TABLE_MAXNAMELEN];
|
||||||
|
@ -2367,7 +2367,7 @@ static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
|
||||||
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
|
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
/* try real handler in case userland supplied needed padding */
|
/* try real handler in case userland supplied needed padding */
|
||||||
if (in_compat_syscall() &&
|
if (in_compat_syscall() &&
|
||||||
((cmd != EBT_SO_GET_INFO && cmd != EBT_SO_GET_INIT_INFO) ||
|
((cmd != EBT_SO_GET_INFO && cmd != EBT_SO_GET_INIT_INFO) ||
|
||||||
|
@ -2434,7 +2434,7 @@ static int do_ebt_set_ctl(struct sock *sk, int cmd, sockptr_t arg,
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case EBT_SO_SET_ENTRIES:
|
case EBT_SO_SET_ENTRIES:
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
if (in_compat_syscall())
|
if (in_compat_syscall())
|
||||||
ret = compat_do_replace(net, arg, len);
|
ret = compat_do_replace(net, arg, len);
|
||||||
else
|
else
|
||||||
|
@ -2442,7 +2442,7 @@ static int do_ebt_set_ctl(struct sock *sk, int cmd, sockptr_t arg,
|
||||||
ret = do_replace(net, arg, len);
|
ret = do_replace(net, arg, len);
|
||||||
break;
|
break;
|
||||||
case EBT_SO_SET_COUNTERS:
|
case EBT_SO_SET_COUNTERS:
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
if (in_compat_syscall())
|
if (in_compat_syscall())
|
||||||
ret = compat_update_counters(net, arg, len);
|
ret = compat_update_counters(net, arg, len);
|
||||||
else
|
else
|
||||||
|
|
|
@ -713,7 +713,7 @@ static int copy_entries_to_user(unsigned int total_size,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
static void compat_standard_from_user(void *dst, const void *src)
|
static void compat_standard_from_user(void *dst, const void *src)
|
||||||
{
|
{
|
||||||
int v = *(compat_int_t *)src;
|
int v = *(compat_int_t *)src;
|
||||||
|
@ -800,7 +800,7 @@ static int get_info(struct net *net, void __user *user, const int *len)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
name[XT_TABLE_MAXNAMELEN-1] = '\0';
|
name[XT_TABLE_MAXNAMELEN-1] = '\0';
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
if (in_compat_syscall())
|
if (in_compat_syscall())
|
||||||
xt_compat_lock(NFPROTO_ARP);
|
xt_compat_lock(NFPROTO_ARP);
|
||||||
#endif
|
#endif
|
||||||
|
@ -808,7 +808,7 @@ static int get_info(struct net *net, void __user *user, const int *len)
|
||||||
if (!IS_ERR(t)) {
|
if (!IS_ERR(t)) {
|
||||||
struct arpt_getinfo info;
|
struct arpt_getinfo info;
|
||||||
const struct xt_table_info *private = t->private;
|
const struct xt_table_info *private = t->private;
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
struct xt_table_info tmp;
|
struct xt_table_info tmp;
|
||||||
|
|
||||||
if (in_compat_syscall()) {
|
if (in_compat_syscall()) {
|
||||||
|
@ -835,7 +835,7 @@ static int get_info(struct net *net, void __user *user, const int *len)
|
||||||
module_put(t->me);
|
module_put(t->me);
|
||||||
} else
|
} else
|
||||||
ret = PTR_ERR(t);
|
ret = PTR_ERR(t);
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
if (in_compat_syscall())
|
if (in_compat_syscall())
|
||||||
xt_compat_unlock(NFPROTO_ARP);
|
xt_compat_unlock(NFPROTO_ARP);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1044,7 +1044,7 @@ static int do_add_counters(struct net *net, sockptr_t arg, unsigned int len)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
struct compat_arpt_replace {
|
struct compat_arpt_replace {
|
||||||
char name[XT_TABLE_MAXNAMELEN];
|
char name[XT_TABLE_MAXNAMELEN];
|
||||||
u32 valid_hooks;
|
u32 valid_hooks;
|
||||||
|
@ -1412,7 +1412,7 @@ static int do_arpt_set_ctl(struct sock *sk, int cmd, sockptr_t arg,
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case ARPT_SO_SET_REPLACE:
|
case ARPT_SO_SET_REPLACE:
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
if (in_compat_syscall())
|
if (in_compat_syscall())
|
||||||
ret = compat_do_replace(sock_net(sk), arg, len);
|
ret = compat_do_replace(sock_net(sk), arg, len);
|
||||||
else
|
else
|
||||||
|
@ -1444,7 +1444,7 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARPT_SO_GET_ENTRIES:
|
case ARPT_SO_GET_ENTRIES:
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
if (in_compat_syscall())
|
if (in_compat_syscall())
|
||||||
ret = compat_get_entries(sock_net(sk), user, len);
|
ret = compat_get_entries(sock_net(sk), user, len);
|
||||||
else
|
else
|
||||||
|
@ -1580,7 +1580,7 @@ static struct xt_target arpt_builtin_tg[] __read_mostly = {
|
||||||
.name = XT_STANDARD_TARGET,
|
.name = XT_STANDARD_TARGET,
|
||||||
.targetsize = sizeof(int),
|
.targetsize = sizeof(int),
|
||||||
.family = NFPROTO_ARP,
|
.family = NFPROTO_ARP,
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
.compatsize = sizeof(compat_int_t),
|
.compatsize = sizeof(compat_int_t),
|
||||||
.compat_from_user = compat_standard_from_user,
|
.compat_from_user = compat_standard_from_user,
|
||||||
.compat_to_user = compat_standard_to_user,
|
.compat_to_user = compat_standard_to_user,
|
||||||
|
|
|
@ -868,7 +868,7 @@ copy_entries_to_user(unsigned int total_size,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
static void compat_standard_from_user(void *dst, const void *src)
|
static void compat_standard_from_user(void *dst, const void *src)
|
||||||
{
|
{
|
||||||
int v = *(compat_int_t *)src;
|
int v = *(compat_int_t *)src;
|
||||||
|
@ -957,7 +957,7 @@ static int get_info(struct net *net, void __user *user, const int *len)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
name[XT_TABLE_MAXNAMELEN-1] = '\0';
|
name[XT_TABLE_MAXNAMELEN-1] = '\0';
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
if (in_compat_syscall())
|
if (in_compat_syscall())
|
||||||
xt_compat_lock(AF_INET);
|
xt_compat_lock(AF_INET);
|
||||||
#endif
|
#endif
|
||||||
|
@ -965,7 +965,7 @@ static int get_info(struct net *net, void __user *user, const int *len)
|
||||||
if (!IS_ERR(t)) {
|
if (!IS_ERR(t)) {
|
||||||
struct ipt_getinfo info;
|
struct ipt_getinfo info;
|
||||||
const struct xt_table_info *private = t->private;
|
const struct xt_table_info *private = t->private;
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
struct xt_table_info tmp;
|
struct xt_table_info tmp;
|
||||||
|
|
||||||
if (in_compat_syscall()) {
|
if (in_compat_syscall()) {
|
||||||
|
@ -993,7 +993,7 @@ static int get_info(struct net *net, void __user *user, const int *len)
|
||||||
module_put(t->me);
|
module_put(t->me);
|
||||||
} else
|
} else
|
||||||
ret = PTR_ERR(t);
|
ret = PTR_ERR(t);
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
if (in_compat_syscall())
|
if (in_compat_syscall())
|
||||||
xt_compat_unlock(AF_INET);
|
xt_compat_unlock(AF_INET);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1199,7 +1199,7 @@ do_add_counters(struct net *net, sockptr_t arg, unsigned int len)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
struct compat_ipt_replace {
|
struct compat_ipt_replace {
|
||||||
char name[XT_TABLE_MAXNAMELEN];
|
char name[XT_TABLE_MAXNAMELEN];
|
||||||
u32 valid_hooks;
|
u32 valid_hooks;
|
||||||
|
@ -1621,7 +1621,7 @@ do_ipt_set_ctl(struct sock *sk, int cmd, sockptr_t arg, unsigned int len)
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case IPT_SO_SET_REPLACE:
|
case IPT_SO_SET_REPLACE:
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
if (in_compat_syscall())
|
if (in_compat_syscall())
|
||||||
ret = compat_do_replace(sock_net(sk), arg, len);
|
ret = compat_do_replace(sock_net(sk), arg, len);
|
||||||
else
|
else
|
||||||
|
@ -1654,7 +1654,7 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IPT_SO_GET_ENTRIES:
|
case IPT_SO_GET_ENTRIES:
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
if (in_compat_syscall())
|
if (in_compat_syscall())
|
||||||
ret = compat_get_entries(sock_net(sk), user, len);
|
ret = compat_get_entries(sock_net(sk), user, len);
|
||||||
else
|
else
|
||||||
|
@ -1846,7 +1846,7 @@ static struct xt_target ipt_builtin_tg[] __read_mostly = {
|
||||||
.name = XT_STANDARD_TARGET,
|
.name = XT_STANDARD_TARGET,
|
||||||
.targetsize = sizeof(int),
|
.targetsize = sizeof(int),
|
||||||
.family = NFPROTO_IPV4,
|
.family = NFPROTO_IPV4,
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
.compatsize = sizeof(compat_int_t),
|
.compatsize = sizeof(compat_int_t),
|
||||||
.compat_from_user = compat_standard_from_user,
|
.compat_from_user = compat_standard_from_user,
|
||||||
.compat_to_user = compat_standard_to_user,
|
.compat_to_user = compat_standard_to_user,
|
||||||
|
|
|
@ -541,7 +541,7 @@ static void clusterip_tg_destroy(const struct xt_tgdtor_param *par)
|
||||||
nf_ct_netns_put(par->net, par->family);
|
nf_ct_netns_put(par->net, par->family);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
struct compat_ipt_clusterip_tgt_info
|
struct compat_ipt_clusterip_tgt_info
|
||||||
{
|
{
|
||||||
u_int32_t flags;
|
u_int32_t flags;
|
||||||
|
@ -553,7 +553,7 @@ struct compat_ipt_clusterip_tgt_info
|
||||||
u_int32_t hash_initval;
|
u_int32_t hash_initval;
|
||||||
compat_uptr_t config;
|
compat_uptr_t config;
|
||||||
};
|
};
|
||||||
#endif /* CONFIG_COMPAT */
|
#endif /* CONFIG_NETFILTER_XTABLES_COMPAT */
|
||||||
|
|
||||||
static struct xt_target clusterip_tg_reg __read_mostly = {
|
static struct xt_target clusterip_tg_reg __read_mostly = {
|
||||||
.name = "CLUSTERIP",
|
.name = "CLUSTERIP",
|
||||||
|
@ -563,9 +563,9 @@ static struct xt_target clusterip_tg_reg __read_mostly = {
|
||||||
.destroy = clusterip_tg_destroy,
|
.destroy = clusterip_tg_destroy,
|
||||||
.targetsize = sizeof(struct ipt_clusterip_tgt_info),
|
.targetsize = sizeof(struct ipt_clusterip_tgt_info),
|
||||||
.usersize = offsetof(struct ipt_clusterip_tgt_info, config),
|
.usersize = offsetof(struct ipt_clusterip_tgt_info, config),
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
.compatsize = sizeof(struct compat_ipt_clusterip_tgt_info),
|
.compatsize = sizeof(struct compat_ipt_clusterip_tgt_info),
|
||||||
#endif /* CONFIG_COMPAT */
|
#endif /* CONFIG_NETFILTER_XTABLES_COMPAT */
|
||||||
.me = THIS_MODULE
|
.me = THIS_MODULE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -884,7 +884,7 @@ copy_entries_to_user(unsigned int total_size,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
static void compat_standard_from_user(void *dst, const void *src)
|
static void compat_standard_from_user(void *dst, const void *src)
|
||||||
{
|
{
|
||||||
int v = *(compat_int_t *)src;
|
int v = *(compat_int_t *)src;
|
||||||
|
@ -973,7 +973,7 @@ static int get_info(struct net *net, void __user *user, const int *len)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
name[XT_TABLE_MAXNAMELEN-1] = '\0';
|
name[XT_TABLE_MAXNAMELEN-1] = '\0';
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
if (in_compat_syscall())
|
if (in_compat_syscall())
|
||||||
xt_compat_lock(AF_INET6);
|
xt_compat_lock(AF_INET6);
|
||||||
#endif
|
#endif
|
||||||
|
@ -981,7 +981,7 @@ static int get_info(struct net *net, void __user *user, const int *len)
|
||||||
if (!IS_ERR(t)) {
|
if (!IS_ERR(t)) {
|
||||||
struct ip6t_getinfo info;
|
struct ip6t_getinfo info;
|
||||||
const struct xt_table_info *private = t->private;
|
const struct xt_table_info *private = t->private;
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
struct xt_table_info tmp;
|
struct xt_table_info tmp;
|
||||||
|
|
||||||
if (in_compat_syscall()) {
|
if (in_compat_syscall()) {
|
||||||
|
@ -1009,7 +1009,7 @@ static int get_info(struct net *net, void __user *user, const int *len)
|
||||||
module_put(t->me);
|
module_put(t->me);
|
||||||
} else
|
} else
|
||||||
ret = PTR_ERR(t);
|
ret = PTR_ERR(t);
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
if (in_compat_syscall())
|
if (in_compat_syscall())
|
||||||
xt_compat_unlock(AF_INET6);
|
xt_compat_unlock(AF_INET6);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1215,7 +1215,7 @@ do_add_counters(struct net *net, sockptr_t arg, unsigned int len)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
struct compat_ip6t_replace {
|
struct compat_ip6t_replace {
|
||||||
char name[XT_TABLE_MAXNAMELEN];
|
char name[XT_TABLE_MAXNAMELEN];
|
||||||
u32 valid_hooks;
|
u32 valid_hooks;
|
||||||
|
@ -1630,7 +1630,7 @@ do_ip6t_set_ctl(struct sock *sk, int cmd, sockptr_t arg, unsigned int len)
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case IP6T_SO_SET_REPLACE:
|
case IP6T_SO_SET_REPLACE:
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
if (in_compat_syscall())
|
if (in_compat_syscall())
|
||||||
ret = compat_do_replace(sock_net(sk), arg, len);
|
ret = compat_do_replace(sock_net(sk), arg, len);
|
||||||
else
|
else
|
||||||
|
@ -1663,7 +1663,7 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IP6T_SO_GET_ENTRIES:
|
case IP6T_SO_GET_ENTRIES:
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
if (in_compat_syscall())
|
if (in_compat_syscall())
|
||||||
ret = compat_get_entries(sock_net(sk), user, len);
|
ret = compat_get_entries(sock_net(sk), user, len);
|
||||||
else
|
else
|
||||||
|
@ -1853,7 +1853,7 @@ static struct xt_target ip6t_builtin_tg[] __read_mostly = {
|
||||||
.name = XT_STANDARD_TARGET,
|
.name = XT_STANDARD_TARGET,
|
||||||
.targetsize = sizeof(int),
|
.targetsize = sizeof(int),
|
||||||
.family = NFPROTO_IPV6,
|
.family = NFPROTO_IPV6,
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
.compatsize = sizeof(compat_int_t),
|
.compatsize = sizeof(compat_int_t),
|
||||||
.compat_from_user = compat_standard_from_user,
|
.compat_from_user = compat_standard_from_user,
|
||||||
.compat_to_user = compat_standard_to_user,
|
.compat_to_user = compat_standard_to_user,
|
||||||
|
|
|
@ -728,6 +728,16 @@ config NETFILTER_XTABLES
|
||||||
|
|
||||||
if NETFILTER_XTABLES
|
if NETFILTER_XTABLES
|
||||||
|
|
||||||
|
config NETFILTER_XTABLES_COMPAT
|
||||||
|
bool "Netfilter Xtables 32bit support"
|
||||||
|
depends on COMPAT
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
This option provides a translation layer to run 32bit arp,ip(6),ebtables
|
||||||
|
binaries on 64bit kernels.
|
||||||
|
|
||||||
|
If unsure, say N.
|
||||||
|
|
||||||
comment "Xtables combined modules"
|
comment "Xtables combined modules"
|
||||||
|
|
||||||
config NETFILTER_XT_MARK
|
config NETFILTER_XT_MARK
|
||||||
|
|
|
@ -52,7 +52,7 @@ struct xt_af {
|
||||||
struct mutex mutex;
|
struct mutex mutex;
|
||||||
struct list_head match;
|
struct list_head match;
|
||||||
struct list_head target;
|
struct list_head target;
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
struct mutex compat_mutex;
|
struct mutex compat_mutex;
|
||||||
struct compat_delta *compat_tab;
|
struct compat_delta *compat_tab;
|
||||||
unsigned int number; /* number of slots in compat_tab[] */
|
unsigned int number; /* number of slots in compat_tab[] */
|
||||||
|
@ -647,7 +647,7 @@ static bool error_tg_ok(unsigned int usersize, unsigned int kernsize,
|
||||||
return usersize == kernsize && strnlen(msg, msglen) < msglen;
|
return usersize == kernsize && strnlen(msg, msglen) < msglen;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
int xt_compat_add_offset(u_int8_t af, unsigned int offset, int delta)
|
int xt_compat_add_offset(u_int8_t af, unsigned int offset, int delta)
|
||||||
{
|
{
|
||||||
struct xt_af *xp = &xt[af];
|
struct xt_af *xp = &xt[af];
|
||||||
|
@ -850,7 +850,7 @@ int xt_compat_check_entry_offsets(const void *base, const char *elems,
|
||||||
__alignof__(struct compat_xt_entry_match));
|
__alignof__(struct compat_xt_entry_match));
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(xt_compat_check_entry_offsets);
|
EXPORT_SYMBOL(xt_compat_check_entry_offsets);
|
||||||
#endif /* CONFIG_COMPAT */
|
#endif /* CONFIG_NETFILTER_XTABLES_COMPAT */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xt_check_entry_offsets - validate arp/ip/ip6t_entry
|
* xt_check_entry_offsets - validate arp/ip/ip6t_entry
|
||||||
|
@ -868,7 +868,7 @@ EXPORT_SYMBOL(xt_compat_check_entry_offsets);
|
||||||
* match structures are aligned, and that the last structure ends where
|
* match structures are aligned, and that the last structure ends where
|
||||||
* the target structure begins.
|
* the target structure begins.
|
||||||
*
|
*
|
||||||
* Also see xt_compat_check_entry_offsets for CONFIG_COMPAT version.
|
* Also see xt_compat_check_entry_offsets for CONFIG_NETFILTER_XTABLES_COMPAT version.
|
||||||
*
|
*
|
||||||
* The arp/ip/ip6t_entry structure @base must have passed following tests:
|
* The arp/ip/ip6t_entry structure @base must have passed following tests:
|
||||||
* - it must point to a valid memory location
|
* - it must point to a valid memory location
|
||||||
|
@ -1059,7 +1059,7 @@ void *xt_copy_counters(sockptr_t arg, unsigned int len,
|
||||||
void *mem;
|
void *mem;
|
||||||
u64 size;
|
u64 size;
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
if (in_compat_syscall()) {
|
if (in_compat_syscall()) {
|
||||||
/* structures only differ in size due to alignment */
|
/* structures only differ in size due to alignment */
|
||||||
struct compat_xt_counters_info compat_tmp;
|
struct compat_xt_counters_info compat_tmp;
|
||||||
|
@ -1106,7 +1106,7 @@ void *xt_copy_counters(sockptr_t arg, unsigned int len,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xt_copy_counters);
|
EXPORT_SYMBOL_GPL(xt_copy_counters);
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
int xt_compat_target_offset(const struct xt_target *target)
|
int xt_compat_target_offset(const struct xt_target *target)
|
||||||
{
|
{
|
||||||
u_int16_t csize = target->compatsize ? : target->targetsize;
|
u_int16_t csize = target->compatsize ? : target->targetsize;
|
||||||
|
@ -1293,7 +1293,7 @@ void xt_table_unlock(struct xt_table *table)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xt_table_unlock);
|
EXPORT_SYMBOL_GPL(xt_table_unlock);
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
void xt_compat_lock(u_int8_t af)
|
void xt_compat_lock(u_int8_t af)
|
||||||
{
|
{
|
||||||
mutex_lock(&xt[af].compat_mutex);
|
mutex_lock(&xt[af].compat_mutex);
|
||||||
|
@ -1931,7 +1931,7 @@ static int __init xt_init(void)
|
||||||
|
|
||||||
for (i = 0; i < NFPROTO_NUMPROTO; i++) {
|
for (i = 0; i < NFPROTO_NUMPROTO; i++) {
|
||||||
mutex_init(&xt[i].mutex);
|
mutex_init(&xt[i].mutex);
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
mutex_init(&xt[i].compat_mutex);
|
mutex_init(&xt[i].compat_mutex);
|
||||||
xt[i].compat_tab = NULL;
|
xt[i].compat_tab = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -134,7 +134,7 @@ static void limit_mt_destroy(const struct xt_mtdtor_param *par)
|
||||||
kfree(info->master);
|
kfree(info->master);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
struct compat_xt_rateinfo {
|
struct compat_xt_rateinfo {
|
||||||
u_int32_t avg;
|
u_int32_t avg;
|
||||||
u_int32_t burst;
|
u_int32_t burst;
|
||||||
|
@ -176,7 +176,7 @@ static int limit_mt_compat_to_user(void __user *dst, const void *src)
|
||||||
};
|
};
|
||||||
return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0;
|
return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_COMPAT */
|
#endif /* CONFIG_NETFILTER_XTABLES_COMPAT */
|
||||||
|
|
||||||
static struct xt_match limit_mt_reg __read_mostly = {
|
static struct xt_match limit_mt_reg __read_mostly = {
|
||||||
.name = "limit",
|
.name = "limit",
|
||||||
|
@ -186,7 +186,7 @@ static struct xt_match limit_mt_reg __read_mostly = {
|
||||||
.checkentry = limit_mt_check,
|
.checkentry = limit_mt_check,
|
||||||
.destroy = limit_mt_destroy,
|
.destroy = limit_mt_destroy,
|
||||||
.matchsize = sizeof(struct xt_rateinfo),
|
.matchsize = sizeof(struct xt_rateinfo),
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
|
||||||
.compatsize = sizeof(struct compat_xt_rateinfo),
|
.compatsize = sizeof(struct compat_xt_rateinfo),
|
||||||
.compat_from_user = limit_mt_compat_from_user,
|
.compat_from_user = limit_mt_compat_from_user,
|
||||||
.compat_to_user = limit_mt_compat_to_user,
|
.compat_to_user = limit_mt_compat_to_user,
|
||||||
|
|
Loading…
Reference in New Issue