mirror of https://github.com/fail2ban/fail2ban
Merge remote-tracking branch 'pr/167/head': FD_CLOEXEC bug fixes (filters) + support (actions). Avoid sockets descriptors leak.
* pr/167/head: FD_CLOEXEC supportpull/172/merge
commit
301460f451
|
@ -29,7 +29,7 @@ __license__ = "GPL"
|
|||
|
||||
from pickle import dumps, loads, HIGHEST_PROTOCOL
|
||||
from common import helpers
|
||||
import asyncore, asynchat, socket, os, logging, sys, traceback
|
||||
import asyncore, asynchat, socket, os, logging, sys, traceback, fcntl
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.server")
|
||||
|
@ -107,6 +107,7 @@ class AsyncServer(asyncore.dispatcher):
|
|||
except TypeError:
|
||||
logSys.warning("Type error")
|
||||
return
|
||||
AsyncServer.__markCloseOnExec(conn)
|
||||
# Creates an instance of the handler class to handle the
|
||||
# request/response on the incoming connection.
|
||||
RequestHandler(conn, self.__transmitter)
|
||||
|
@ -134,6 +135,7 @@ class AsyncServer(asyncore.dispatcher):
|
|||
self.bind(sock)
|
||||
except Exception:
|
||||
raise AsyncServerException("Unable to bind socket %s" % self.__sock)
|
||||
AsyncServer.__markCloseOnExec(self.socket)
|
||||
self.listen(1)
|
||||
# Sets the init flag.
|
||||
self.__init = True
|
||||
|
@ -159,6 +161,18 @@ class AsyncServer(asyncore.dispatcher):
|
|||
os.remove(self.__sock)
|
||||
logSys.debug("Socket shutdown")
|
||||
|
||||
##
|
||||
# Marks socket as close-on-exec to avoid leaking file descriptors when
|
||||
# running actions involving command execution.
|
||||
|
||||
# @param sock: socket file.
|
||||
|
||||
#@staticmethod
|
||||
def __markCloseOnExec(sock):
|
||||
fd = sock.fileno()
|
||||
flags = fcntl.fcntl(fd, fcntl.F_GETFD)
|
||||
fcntl.fcntl(fd, fcntl.F_SETFD, flags|fcntl.FD_CLOEXEC)
|
||||
__markCloseOnExec = staticmethod(__markCloseOnExec)
|
||||
|
||||
##
|
||||
# AsyncServerException is used to wrap communication exceptions.
|
||||
|
|
|
@ -554,7 +554,8 @@ class FileContainer:
|
|||
self.__handler = open(self.__filename)
|
||||
# Set the file descriptor to be FD_CLOEXEC
|
||||
fd = self.__handler.fileno()
|
||||
fcntl.fcntl(fd, fcntl.F_SETFD, fd | fcntl.FD_CLOEXEC)
|
||||
flags = fcntl.fcntl(fd, fcntl.F_GETFD)
|
||||
fcntl.fcntl(fd, fcntl.F_SETFD, flags | fcntl.FD_CLOEXEC)
|
||||
firstLine = self.__handler.readline()
|
||||
# Computes the MD5 of the first line.
|
||||
myHash = md5sum(firstLine).digest()
|
||||
|
|
|
@ -27,7 +27,7 @@ from failmanager import FailManagerEmpty
|
|||
from filter import FileFilter
|
||||
from mytime import MyTime
|
||||
|
||||
import time, logging, gamin
|
||||
import time, logging, gamin, fcntl
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.filter")
|
||||
|
@ -52,6 +52,9 @@ class FilterGamin(FileFilter):
|
|||
self.__modified = False
|
||||
# Gamin monitor
|
||||
self.monitor = gamin.WatchMonitor()
|
||||
fd = self.monitor.get_fd()
|
||||
flags = fcntl.fcntl(fd, fcntl.F_GETFD)
|
||||
fcntl.fcntl(fd, fcntl.F_SETFD, flags|fcntl.FD_CLOEXEC)
|
||||
logSys.debug("Created FilterGamin")
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue