Skip to content

Commit

Permalink
[NETFILTER]: {ip,ip6,arp}_tables: return EAGAIN for invalid SO_GET_EN…
Browse files Browse the repository at this point in the history
…TRIES 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>
  • Loading branch information
Patrick McHardy committed Apr 14, 2008
1 parent fa913dd commit 544473c
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 6 deletions.
4 changes: 2 additions & 2 deletions net/ipv4/netfilter/arp_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -937,7 +937,7 @@ static int get_entries(struct net *net, struct arpt_get_entries __user *uptr,
else {
duprintf("get_entries: I've got %u not %u!\n",
private->size, get.size);
ret = -EINVAL;
ret = -EAGAIN;
}
module_put(t->me);
xt_table_unlock(t);
Expand Down Expand Up @@ -1621,7 +1621,7 @@ static int compat_get_entries(struct net *net,
} else if (!ret) {
duprintf("compat_get_entries: I've got %u not %u!\n",
private->size, get.size);
ret = -EINVAL;
ret = -EAGAIN;
}
xt_compat_flush_offsets(NF_ARP);
module_put(t->me);
Expand Down
4 changes: 2 additions & 2 deletions net/ipv4/netfilter/ip_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -1180,7 +1180,7 @@ get_entries(struct net *net, struct ipt_get_entries __user *uptr, int *len)
else {
duprintf("get_entries: I've got %u not %u!\n",
private->size, get.size);
ret = -EINVAL;
ret = -EAGAIN;
}
module_put(t->me);
xt_table_unlock(t);
Expand Down Expand Up @@ -1939,7 +1939,7 @@ compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr,
} else if (!ret) {
duprintf("compat_get_entries: I've got %u not %u!\n",
private->size, get.size);
ret = -EINVAL;
ret = -EAGAIN;
}
xt_compat_flush_offsets(AF_INET);
module_put(t->me);
Expand Down
4 changes: 2 additions & 2 deletions net/ipv6/netfilter/ip6_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -1206,7 +1206,7 @@ get_entries(struct net *net, struct ip6t_get_entries __user *uptr, int *len)
else {
duprintf("get_entries: I've got %u not %u!\n",
private->size, get.size);
ret = -EINVAL;
ret = -EAGAIN;
}
module_put(t->me);
xt_table_unlock(t);
Expand Down Expand Up @@ -1966,7 +1966,7 @@ compat_get_entries(struct net *net, struct compat_ip6t_get_entries __user *uptr,
} else if (!ret) {
duprintf("compat_get_entries: I've got %u not %u!\n",
private->size, get.size);
ret = -EINVAL;
ret = -EAGAIN;
}
xt_compat_flush_offsets(AF_INET6);
module_put(t->me);
Expand Down

0 comments on commit 544473c

Please sign in to comment.