net/ipv4/netfilter/ip_tables.c | 37 +++++++++++++++++++++++++++
2 files changed, 38 insertions(+)
-diff --git a/include/uapi/linux/netfilter_ipv4/ip_tables.h b/include/uapi/linux/netfilter_ipv4/ip_tables.h
-index d0da53d96d93..f279daa13c0f 100644
--- a/include/uapi/linux/netfilter_ipv4/ip_tables.h
+++ b/include/uapi/linux/netfilter_ipv4/ip_tables.h
@@ -88,6 +88,7 @@ struct ipt_ip {
/* Values for "inv" field in struct ipt_ip. */
#define IPT_INV_VIA_IN 0x01 /* Invert the sense of IN IFACE. */
-diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
-index 7c00ce90adb8..d919350a0e8b 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -58,6 +58,9 @@ ip_packet_match(const struct iphdr *ip,
static bool
ip_checkentry(const struct ipt_ip *ip)
{
-@@ -545,6 +571,8 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name,
+@@ -550,6 +576,8 @@ find_check_entry(struct ipt_entry *e, st
+ struct xt_mtchk_param mtpar;
struct xt_entry_match *ematch;
- unsigned long pcnt;
+ ip_checkdefault(&e->ip);
+
- pcnt = xt_percpu_counter_alloc();
- if (IS_ERR_VALUE(pcnt))
+ if (!xt_percpu_counter_alloc(alloc_state, &e->counters))
return -ENOMEM;
-@@ -824,6 +852,7 @@ copy_entries_to_user(unsigned int total_size,
+
+@@ -829,6 +857,7 @@ copy_entries_to_user(unsigned int total_
const struct xt_table_info *private = table->private;
int ret = 0;
const void *loc_cpu_entry;
counters = alloc_counters(table);
if (IS_ERR(counters))
-@@ -851,6 +880,14 @@ copy_entries_to_user(unsigned int total_size,
+@@ -856,6 +885,14 @@ copy_entries_to_user(unsigned int total_
goto free_counters;
}
for (i = sizeof(struct ipt_entry);
i < e->target_offset;
i += m->u.match_size) {
---
-2.11.0
-
+@@ -1245,12 +1282,15 @@ compat_copy_entry_to_user(struct ipt_ent
+ compat_uint_t origsize;
+ const struct xt_entry_match *ematch;
+ int ret = 0;
++ u8 flags = e->ip.flags & IPT_F_MASK;
+
+ origsize = *size;
+ ce = (struct compat_ipt_entry __user *)*dstptr;
+ if (copy_to_user(ce, e, sizeof(struct ipt_entry)) != 0 ||
+ copy_to_user(&ce->counters, &counters[i],
+- sizeof(counters[i])) != 0)
++ sizeof(counters[i])) != 0 ||
++ copy_to_user(&ce->ip.flags, &flags,
++ sizeof(flags)) != 0)
+ return -EFAULT;
+
+ *dstptr += sizeof(struct compat_ipt_entry);