diff -Nru apport-2.20.9/apport/hookutils.py apport-2.20.9/apport/hookutils.py --- apport-2.20.9/apport/hookutils.py 2020-08-05 20:56:32.000000000 -0400 +++ apport-2.20.9/apport/hookutils.py 2021-05-12 06:46:16.000000000 -0400 @@ -76,8 +76,14 @@ instead of failing. ''' try: - with open(path, 'rb') as f: - contents = f.read().strip() + # make sure the file isn't a FIFO or symlink + fd = os.open(path, os.O_NOFOLLOW | os.O_RDONLY | os.O_NONBLOCK) + st = os.fstat(fd) + if stat.S_ISREG(st.st_mode): + with os.fdopen(fd, 'rb') as f: + contents = f.read().strip() + else: + return 'Error: could not open file!' if force_unicode: return contents.decode('UTF-8', errors='replace') try: diff -Nru apport-2.20.9/backends/packaging-apt-dpkg.py apport-2.20.9/backends/packaging-apt-dpkg.py --- apport-2.20.9/backends/packaging-apt-dpkg.py 2019-11-11 16:57:56.000000000 -0500 +++ apport-2.20.9/backends/packaging-apt-dpkg.py 2021-05-12 06:46:16.000000000 -0400 @@ -401,7 +401,7 @@ allows filtering. ''' dpkg = subprocess.Popen(['dpkg-query', '-W', '--showformat=${Conffiles}', - package], stdout=subprocess.PIPE) + '--', package], stdout=subprocess.PIPE) out = dpkg.communicate()[0].decode() if dpkg.returncode != 0: diff -Nru apport-2.20.9/data/whoopsie-upload-all apport-2.20.9/data/whoopsie-upload-all --- apport-2.20.9/data/whoopsie-upload-all 2019-11-11 16:57:56.000000000 -0500 +++ apport-2.20.9/data/whoopsie-upload-all 2021-05-12 06:46:16.000000000 -0400 @@ -14,6 +14,7 @@ # the full text of the license. import os +import stat import sys import time import subprocess @@ -83,11 +84,16 @@ os.unlink(report) return None - # write updated report - with open(report, 'ab') as f: - os.chmod(report, 0) - r.write(f, only_new=True) - os.chmod(report, 0o640) + # write updated report, we use os.open and os.fdopen as + # /proc/sys/fs/protected_regular is set to 1 (LP: #1848064) + # make sure the file isn't a FIFO or symlink + fd = os.open(report, os.O_NOFOLLOW | os.O_WRONLY | os.O_APPEND | os.O_NONBLOCK) + st = os.fstat(fd) + if stat.S_ISREG(st.st_mode): + with os.fdopen(fd, 'wb') as f: + os.fchmod(fd, 0) + r.write(f, only_new=True) + os.fchmod(fd, 0o640) # now tell whoopsie to upload the report print('Marking %s for whoopsie upload' % report) diff -Nru apport-2.20.9/debian/changelog apport-2.20.9/debian/changelog --- apport-2.20.9/debian/changelog 2021-01-26 07:21:46.000000000 -0500 +++ apport-2.20.9/debian/changelog 2021-05-12 06:46:16.000000000 -0400 @@ -1,3 +1,24 @@ +apport (2.20.9-0ubuntu7.24) bionic-security; urgency=medium + + * SECURITY UPDATE: Multiple arbitrary file reads (LP: #1917904) + - apport/hookutils.py: don't follow symlinks and make sure the file + isn't a FIFO in read_file(). + - test/test_hookutils.py: added symlink tests. + - CVE-2021-32547, CVE-2021-32548, CVE-2021-32549, CVE-2021-32550, + CVE-2021-32551, CVE-2021-32552, CVE-2021-32553, CVE-2021-32554, + CVE-2021-32555 + * SECURITY UPDATE: info disclosure via modified config files spoofing + (LP: #1917904) + - backends/packaging-apt-dpkg.py: properly terminate arguments in + get_modified_conffiles. + - CVE-2021-32556 + * SECURITY UPDATE: arbitrary file write (LP: #1917904) + - data/whoopsie-upload-all: don't follow symlinks and make sure the + file isn't a FIFO in process_report(). + - CVE-2021-32557 + + -- Marc Deslauriers Wed, 12 May 2021 06:46:16 -0400 + apport (2.20.9-0ubuntu7.23) bionic-security; urgency=medium * SECURITY UPDATE: multiple security issues (LP: #1912326) diff -Nru apport-2.20.9/test/test_hookutils.py apport-2.20.9/test/test_hookutils.py --- apport-2.20.9/test/test_hookutils.py 2019-11-11 16:57:56.000000000 -0500 +++ apport-2.20.9/test/test_hookutils.py 2021-05-12 06:46:16.000000000 -0400 @@ -1,5 +1,5 @@ # coding: UTF-8 -import unittest, tempfile, locale, subprocess, re, shutil, os.path, sys +import unittest, tempfile, locale, subprocess, re, shutil, os, sys import apport.hookutils @@ -93,6 +93,14 @@ self.assertEqual(list(report), ['.nonexisting']) self.assertTrue(report['.nonexisting'].startswith('Error: ')) + # symlink + link = os.path.join(self.workdir, 'symlink') + os.symlink('/etc/passwd', link) + report = {} + apport.hookutils.attach_file(report, link, 'Symlink') + self.assertEqual(list(report), ['Symlink']) + self.assertTrue(report['Symlink'].startswith('Error: ')) + # existing key report = {} apport.hookutils.attach_file(report, '/etc/passwd') @@ -137,6 +145,14 @@ self.assertEqual(list(report), ['Passwd']) self.assertEqual(report['Passwd'], passwd_contents) + # symlink + link = os.path.join(self.workdir, 'symlink') + os.symlink('/etc/passwd', link) + report = {} + apport.hookutils.attach_file_if_exists(report, link, 'Symlink') + self.assertEqual(list(report), ['Symlink']) + self.assertTrue(report['Symlink'].startswith('Error: ')) + # nonexisting file report = {} apport.hookutils.attach_file_if_exists(report, '/nonexisting')