diff options
author | Florian Westphal <fw@strlen.de> | 2016-04-01 15:37:59 +0200 |
---|---|---|
committer | Jiri Slaby <jslaby@suse.cz> | 2016-07-21 08:35:48 +0200 |
commit | 6a8d4c2659ad0b5b672cafcf81ae0e5fbe18ada8 (patch) | |
tree | a8faa2cf1a32e76c5c9161768469e53dca07b821 /net/ipv6 | |
parent | 737f0730a5e12e9f5dbe49e1817880c2539def06 (diff) | |
download | lwn-6a8d4c2659ad0b5b672cafcf81ae0e5fbe18ada8.tar.gz lwn-6a8d4c2659ad0b5b672cafcf81ae0e5fbe18ada8.zip |
netfilter: x_tables: introduce and use xt_copy_counters_from_user
commit d7591f0c41ce3e67600a982bab6989ef0f07b3ce upstream
The three variants use same copy&pasted code, condense this into a
helper and use that.
Make sure info.name is 0-terminated.
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 49 |
1 files changed, 5 insertions, 44 deletions
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index efbe986a562a..e214222cd06f 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -1300,56 +1300,17 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len, unsigned int i, curcpu; struct xt_counters_info tmp; struct xt_counters *paddc; - unsigned int num_counters; - char *name; - int size; - void *ptmp; struct xt_table *t; const struct xt_table_info *private; int ret = 0; const void *loc_cpu_entry; struct ip6t_entry *iter; unsigned int addend; -#ifdef CONFIG_COMPAT - struct compat_xt_counters_info compat_tmp; - - if (compat) { - ptmp = &compat_tmp; - size = sizeof(struct compat_xt_counters_info); - } else -#endif - { - ptmp = &tmp; - size = sizeof(struct xt_counters_info); - } - - if (copy_from_user(ptmp, user, size) != 0) - return -EFAULT; - -#ifdef CONFIG_COMPAT - if (compat) { - num_counters = compat_tmp.num_counters; - name = compat_tmp.name; - } else -#endif - { - num_counters = tmp.num_counters; - name = tmp.name; - } - - if (len != size + num_counters * sizeof(struct xt_counters)) - return -EINVAL; - - paddc = vmalloc(len - size); - if (!paddc) - return -ENOMEM; - - if (copy_from_user(paddc, user + size, len - size) != 0) { - ret = -EFAULT; - goto free; - } - t = xt_find_table_lock(net, AF_INET6, name); + paddc = xt_copy_counters_from_user(user, len, &tmp, compat); + if (IS_ERR(paddc)) + return PTR_ERR(paddc); + t = xt_find_table_lock(net, AF_INET6, tmp.name); if (IS_ERR_OR_NULL(t)) { ret = t ? PTR_ERR(t) : -ENOENT; goto free; @@ -1358,7 +1319,7 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len, local_bh_disable(); private = t->private; - if (private->number != num_counters) { + if (private->number != tmp.num_counters) { ret = -EINVAL; goto unlock_up_free; } |