[iptables PATCH] iptables-legacy: Fix for mandatory lock waiting

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Parameter 'wait' passed to xtables_lock() signals three modes of
operation, depending on its value:

-1: --wait not specified, do not wait if lock is busy
 0: --wait specified without value, wait indefinitely until lock becomes
    free
>0: Wait for 'wait' seconds for lock to become free, abort otherwise

Since fixed commit, the first two cases were treated the same apart from
calling alarm(0), but that is a nop if no alarm is pending. Fix the code
by requesting a non-blocking flock() in the second case. While at it,
restrict the alarm setup to the third case only.

Cc: Jethro Beekman <jethro@xxxxxxxxxxxx>
Cc: howardjohn@xxxxxxxxxx
Cc: Antonio Ojea <antonio.ojea.garcia@xxxxxxxxx>
Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1728
Fixes: 07e2107ef0cbc ("xshared: Implement xtables lock timeout using signals")
Signed-off-by: Phil Sutter <phil@xxxxxx>
---
 .../shell/testcases/iptables/0010-wait_0      | 55 +++++++++++++++++++
 iptables/xshared.c                            |  4 +-
 2 files changed, 57 insertions(+), 2 deletions(-)
 create mode 100755 iptables/tests/shell/testcases/iptables/0010-wait_0

diff --git a/iptables/tests/shell/testcases/iptables/0010-wait_0 b/iptables/tests/shell/testcases/iptables/0010-wait_0
new file mode 100755
index 0000000000000..4481f966ce435
--- /dev/null
+++ b/iptables/tests/shell/testcases/iptables/0010-wait_0
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+case "$XT_MULTI" in
+*xtables-legacy-multi)
+	;;
+*)
+	echo skip $XT_MULTI
+	exit 0
+	;;
+esac
+
+coproc RESTORE { $XT_MULTI iptables-restore; }
+echo "*filter" >&${RESTORE[1]}
+
+
+$XT_MULTI iptables -A FORWARD -j ACCEPT &
+ipt_pid=$!
+
+waitpid -t 1 $ipt_pid
+[[ $? -eq 3 ]] && {
+	echo "process waits when it should not"
+	exit 1
+}
+wait $ipt_pid
+[[ $? -eq 0 ]] && {
+	echo "process exited 0 despite busy lock"
+	exit 1
+}
+
+t0=$(date +%s)
+$XT_MULTI iptables -w 3 -A FORWARD -j ACCEPT
+t1=$(date +%s)
+[[ $((t1 - t0)) -ge 3 ]] || {
+	echo "wait time not expired"
+	exit 1
+}
+
+$XT_MULTI iptables -w -A FORWARD -j ACCEPT &
+ipt_pid=$!
+
+waitpid -t 3 $ipt_pid
+[[ $? -eq 3 ]] || {
+	echo "no indefinite wait"
+	exit 1
+}
+kill $ipt_pid
+waitpid -t 3 $ipt_pid
+[[ $? -eq 3 ]] && {
+	echo "killed waiting iptables call did not exit in time"
+	exit 1
+}
+
+kill $RESTORE_PID
+wait
+exit 0
diff --git a/iptables/xshared.c b/iptables/xshared.c
index 5cae62b45cdf4..43fa929df7676 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -270,7 +270,7 @@ static int xtables_lock(int wait)
 		return XT_LOCK_FAILED;
 	}
 
-	if (wait != -1) {
+	if (wait > 0) {
 		sigact_alarm.sa_handler = alarm_ignore;
 		sigact_alarm.sa_flags = SA_RESETHAND;
 		sigemptyset(&sigact_alarm.sa_mask);
@@ -278,7 +278,7 @@ static int xtables_lock(int wait)
 		alarm(wait);
 	}
 
-	if (flock(fd, LOCK_EX) == 0)
+	if (flock(fd, LOCK_EX | (wait ? 0 : LOCK_NB)) == 0)
 		return fd;
 
 	if (errno == EINTR) {
-- 
2.43.0





[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux