From 3a58d0e6e40898c5b4ec14cafa625229b4c2081d Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Sat, 24 Sep 2011 02:28:45 +0000 Subject: [PATCH] BF: Lock server's executeCmd to prevent racing among iptables calls (Closes: #554162) Many kudos go to Michael Saavedra for the solution and the patch. git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/branches/FAIL2BAN-0_8@784 a942ae1a-1317-0410-a47c-b1dcaea8d605 --- server/action.py | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/server/action.py b/server/action.py index f55d9a6d4..8dafbf279 100644 --- a/server/action.py +++ b/server/action.py @@ -25,11 +25,15 @@ __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" import logging, os +import threading #from subprocess import call # Gets the instance of the logger. logSys = logging.getLogger("fail2ban.actions.action") +# Create a lock for running system commands +_cmd_lock = threading.Lock() + ## # Execute commands. # @@ -301,17 +305,21 @@ class Action: #@staticmethod def executeCmd(realCmd): logSys.debug(realCmd) - try: - # The following line gives deadlock with multiple jails - #retcode = call(realCmd, shell=True) - retcode = os.system(realCmd) - if retcode == 0: - logSys.debug("%s returned successfully" % realCmd) - return True - else: - logSys.error("%s returned %x" % (realCmd, retcode)) - except OSError, e: - logSys.error("%s failed with %s" % (realCmd, e)) + _cmd_lock.acquire() + try: # Try wrapped within another try needed for python version < 2.5 + try: + # The following line gives deadlock with multiple jails + #retcode = call(realCmd, shell=True) + retcode = os.system(realCmd) + if retcode == 0: + logSys.debug("%s returned successfully" % realCmd) + return True + else: + logSys.error("%s returned %x" % (realCmd, retcode)) + except OSError, e: + logSys.error("%s failed with %s" % (realCmd, e)) + finally: + _cmd_lock.release() return False executeCmd = staticmethod(executeCmd)