aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2008-04-14 05:15:45 -0400
committerPatrick McHardy <kaber@trash.net>2008-04-14 05:15:45 -0400
commit544473c1664f3a688be949ac078bdee6f4afeef1 (patch)
tree019b6a5088f8fe99928464d9530268d1de02924a /net/ipv6
parentfa913ddf6372b20b23061996150d38f639488d42 (diff)
[NETFILTER]: {ip,ip6,arp}_tables: return EAGAIN for invalid SO_GET_ENTRIES size
Rule dumping is performed in two steps: first userspace gets the ruleset size using getsockopt(SO_GET_INFO) and allocates memory, then it calls getsockopt(SO_GET_ENTRIES) to actually dump the ruleset. When another process changes the ruleset in between the sizes from the first getsockopt call doesn't match anymore and the kernel aborts. Unfortunately it returns EAGAIN, as for multiple other possible errors, so userspace can't distinguish this case from real errors. Return EAGAIN so userspace can retry the operation. Fixes (with current iptables SVN version) netfilter bugzilla #104. Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/netfilter/ip6_tables.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 782183f63366..0b4557e03431 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1206,7 +1206,7 @@ get_entries(struct net *net, struct ip6t_get_entries __user *uptr, int *len)
1206 else { 1206 else {
1207 duprintf("get_entries: I've got %u not %u!\n", 1207 duprintf("get_entries: I've got %u not %u!\n",
1208 private->size, get.size); 1208 private->size, get.size);
1209 ret = -EINVAL; 1209 ret = -EAGAIN;
1210 } 1210 }
1211 module_put(t->me); 1211 module_put(t->me);
1212 xt_table_unlock(t); 1212 xt_table_unlock(t);
@@ -1966,7 +1966,7 @@ compat_get_entries(struct net *net, struct compat_ip6t_get_entries __user *uptr,
1966 } else if (!ret) { 1966 } else if (!ret) {
1967 duprintf("compat_get_entries: I've got %u not %u!\n", 1967 duprintf("compat_get_entries: I've got %u not %u!\n",
1968 private->size, get.size); 1968 private->size, get.size);
1969 ret = -EINVAL; 1969 ret = -EAGAIN;
1970 } 1970 }
1971 xt_compat_flush_offsets(AF_INET6); 1971 xt_compat_flush_offsets(AF_INET6);
1972 module_put(t->me); 1972 module_put(t->me);