https://bugs.launchpad.net/ubuntu/+source/iptables/+bug/1187177 http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=710997 ---------- Forwarded message ---------- From: LaMont Jones <lamont@xxxxxxxxxx> Date: Mon, Jun 3, 2013 at 6:07 PM Subject: Bug#710997: iptables calls setsockopt incorrectly To: submit@xxxxxxxxxxxxxxx Package: iptables Version: 1.4.18-1 Tags: patch -- Since time immemorial, iptables has called setsockopt() and treated any -1 return value as fatal. Any system call can return EAGAIN or EINPROGRESS (depending on the origins of the API), and good coding practice requires checking for that and retrying or otherwise handling it. In the case of iptables, if multiple processes are calling iptables concurrently, then it is likely that one of them will fail. I have seen this with xen, as well as certain firewall configurations where the firewall rules are added as triggered by interfaces being discovered and configured. The attached patch fixes the issue. lamont
diff -ur x/iptables-1.4.18/libiptc/libiptc.c iptables-1.4.18/libiptc/libiptc.c --- x/iptables-1.4.18/libiptc/libiptc.c 2013-03-03 14:40:11.000000000 -0700 +++ iptables-1.4.18/libiptc/libiptc.c 2013-06-03 16:03:31.819448019 -0600 @@ -2596,8 +2596,10 @@ } #endif - ret = setsockopt(handle->sockfd, TC_IPPROTO, SO_SET_REPLACE, repl, + do { + ret = setsockopt(handle->sockfd, TC_IPPROTO, SO_SET_REPLACE, repl, sizeof(*repl) + repl->size); + } while ( ret < 0 && ( errno == EAGAIN || errno == EINPROGRESS)); if (ret < 0) goto out_free_newcounters; @@ -2672,8 +2674,10 @@ } #endif - ret = setsockopt(handle->sockfd, TC_IPPROTO, SO_SET_ADD_COUNTERS, + do { + ret = setsockopt(handle->sockfd, TC_IPPROTO, SO_SET_ADD_COUNTERS, newcounters, counterlen); + } while ( ret < 0 && ( errno == EAGAIN || errno == EINPROGRESS)); if (ret < 0) goto out_free_newcounters;