diff -Nru swift-1.13.1/debian/changelog swift-1.13.1/debian/changelog --- swift-1.13.1/debian/changelog 2015-07-22 08:08:22.000000000 -0700 +++ swift-1.13.1/debian/changelog 2017-07-12 09:01:17.000000000 -0700 @@ -1,3 +1,13 @@ +swift (1.13.1-0ubuntu1.3) trusty; urgency=medium + + * Fix issue where swift daemons crash while writing logs to a stopped + rsyslogd /dev/log socket. (LP: #1683076) + - d/patches/fix-infinite-recursion-logging.patch: Cherry-picked from + upstream stable/newton branch to avoid infinite loops when logging + while rsyslogd is stopped. + + -- Billy Olsen Mon, 03 Jul 2017 22:22:58 -0700 + swift (1.13.1-0ubuntu1.2) trusty-security; urgency=medium * SECURITY UPDATE: metadata constraint bypass via multiple requests diff -Nru swift-1.13.1/debian/patches/fix-infinite-recursion-logging.patch swift-1.13.1/debian/patches/fix-infinite-recursion-logging.patch --- swift-1.13.1/debian/patches/fix-infinite-recursion-logging.patch 1969-12-31 17:00:00.000000000 -0700 +++ swift-1.13.1/debian/patches/fix-infinite-recursion-logging.patch 2017-07-12 09:01:10.000000000 -0700 @@ -0,0 +1,145 @@ +From d4e3aab260680b952684b9d390823606751ca3ea Mon Sep 17 00:00:00 2001 +From: Samuel Merritt +Date: Wed, 23 Mar 2016 13:51:47 -0700 +Subject: [PATCH 1/1] Fix infinite recursion during logging when syslog is down + +Change-Id: Ia9ecffc88ce43616977e141498e5ee404f2c29c4 +(cherry picked from commit 95efd3f9035ec4141e1b182516f040a59a3e5aa6) +--- + swift/common/utils.py | 49 ++++++++++++++++++++++++++++++++++++------ + test/unit/common/test_utils.py | 42 ++++++++++++++++++++++++++++++++++++ + 2 files changed, 84 insertions(+), 7 deletions(-) + +Forwarded: Not-Needed +Bug: https://launchpad.net/bugs/1683076 +Origin: backport, https://github.com/openstack/swift/commit/95efd3f9035ec4141e1b182516f040a59a3e5aa6 + +diff --git a/swift/common/utils.py b/swift/common/utils.py +index 8a840ae0..b8996890 100644 +--- a/swift/common/utils.py ++++ b/swift/common/utils.py +@@ -721,19 +721,54 @@ class NullLogger(object): + + class LoggerFileObject(object): + ++ # Note: this is greenthread-local storage ++ _cls_thread_local = threading.local() ++ + def __init__(self, logger): + self.logger = logger + + def write(self, value): +- value = value.strip() +- if value: +- if 'Connection reset by peer' in value: +- self.logger.error(_('STDOUT: Connection reset by peer')) +- else: +- self.logger.error(_('STDOUT: %s'), value) ++ # We can get into a nasty situation when logs are going to syslog ++ # and syslog dies. ++ # ++ # It's something like this: ++ # ++ # (A) someone logs something ++ # ++ # (B) there's an exception in sending to /dev/log since syslog is ++ # not working ++ # ++ # (C) logging takes that exception and writes it to stderr (see ++ # logging.Handler.handleError) ++ # ++ # (D) stderr was replaced with a LoggerFileObject at process start, ++ # so the LoggerFileObject takes the provided string and tells ++ # its logger to log it (to syslog, naturally). ++ # ++ # Then, steps B through D repeat until we run out of stack. ++ if getattr(self._cls_thread_local, 'already_called_write', False): ++ return ++ ++ self._cls_thread_local.already_called_write = True ++ try: ++ value = value.strip() ++ if value: ++ if 'Connection reset by peer' in value: ++ self.logger.error(_('STDOUT: Connection reset by peer')) ++ else: ++ self.logger.error(_('STDOUT: %s'), value) ++ finally: ++ self._cls_thread_local.already_called_write = False + + def writelines(self, values): +- self.logger.error(_('STDOUT: %s'), '#012'.join(values)) ++ if getattr(self._cls_thread_local, 'already_called_writelines', False): ++ return ++ ++ self._cls_thread_local.already_called_writelines = True ++ try: ++ self.logger.error(_('STDOUT: %s'), '#012'.join(values)) ++ finally: ++ self._cls_thread_local.already_called_writelines = False + + def close(self): + pass +diff --git a/test/unit/common/test_utils.py b/test/unit/common/test_utils.py +index 2996f355..9bfc852a 100644 +--- a/test/unit/common/test_utils.py ++++ b/test/unit/common/test_utils.py +@@ -40,6 +40,7 @@ import unittest + import fcntl + import shutil + from contextlib import nested ++from contextlib import closing + + from Queue import Queue, Empty + from getpass import getuser +@@ -439,6 +440,47 @@ class TestUtils(unittest.TestCase): + self.assertRaises(IOError, lfo.readline, 1024) + lfo.tell() + ++ def test_LoggerFileObject_recursion(self): ++ crashy_calls = [0] ++ ++ class CrashyLogger(logging.Handler): ++ def emit(self, record): ++ crashy_calls[0] += 1 ++ try: ++ # Pretend to be trying to send to syslog, but syslogd is ++ # dead. We need the raise here to set sys.exc_info. ++ raise socket.error(errno.ENOTCONN, "This is an ex-syslog") ++ except socket.error: ++ self.handleError(record) ++ ++ logger = logging.getLogger() ++ logger.addHandler(CrashyLogger()) ++ ++ # Set up some real file descriptors for stdio. If you run ++ # nosetests with "-s", you already have real files there, but ++ # otherwise they're StringIO objects. ++ # ++ # In any case, since capture_stdio() closes sys.stdin and friends, ++ # we'd want to set up some sacrificial files so as to not goof up ++ # the testrunner. ++ new_stdin = open(os.devnull, 'r+b') ++ new_stdout = open(os.devnull, 'w+b') ++ new_stderr = open(os.devnull, 'w+b') ++ ++ with closing(new_stdin), closing(new_stdout), closing(new_stderr): ++ # logging.raiseExceptions is set to False in test/__init__.py, but ++ # is True in Swift daemons, and the error doesn't manifest without ++ # it. ++ with patch('sys.stdin', new_stdin), \ ++ patch('sys.stdout', new_stdout), \ ++ patch('sys.stderr', new_stderr), \ ++ patch.object(logging, 'raiseExceptions', True): ++ # Note: since stdio is hooked up to /dev/null in here, using ++ # pdb is basically impossible. Sorry about that. ++ utils.capture_stdio(logger) ++ logger.info("I like ham") ++ self.assertTrue(crashy_calls[0], 1) ++ + def test_parse_options(self): + # Get a file that is definitely on disk + with NamedTemporaryFile() as f: +-- +2.11.0 + diff -Nru swift-1.13.1/debian/patches/series swift-1.13.1/debian/patches/series --- swift-1.13.1/debian/patches/series 2015-07-22 08:02:58.000000000 -0700 +++ swift-1.13.1/debian/patches/series 2017-07-03 23:31:54.000000000 -0700 @@ -4,3 +4,4 @@ CVE-2014-3497.patch CVE-2014-7960.patch CVE-2015-1856.patch +fix-infinite-recursion-logging.patch