Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python311 for openSUSE:Factory checked in at 2024-03-01 23:35:58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python311 (Old) and /work/SRC/openSUSE:Factory/.python311.new.1770 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python311" Fri Mar 1 23:35:58 2024 rev:30 rq:1153186 version:3.11.8 Changes: -------- --- /work/SRC/openSUSE:Factory/python311/python311.changes 2024-02-18 20:22:59.601629160 +0100 +++ /work/SRC/openSUSE:Factory/.python311.new.1770/python311.changes 2024-03-01 23:36:06.566552531 +0100 @@ -1,0 +2,14 @@ +Fri Feb 23 01:06:42 UTC 2024 - Matej Cepl <mc...@suse.com> + +- (bsc#1219666, CVE-2023-6597) Add + CVE-2023-6597-TempDir-cleaning-symlink.patch (patch from + gh#python/cpython!99930) fixing symlink bug in cleanup of + tempfile.TemporaryDirectory. + +------------------------------------------------------------------- +Tue Feb 20 22:14:02 UTC 2024 - Matej Cepl <mc...@cepl.eu> + +- Remove double definition of /usr/bin/idle%%{version} in + %%files. + +------------------------------------------------------------------- New: ---- CVE-2023-6597-TempDir-cleaning-symlink.patch BETA DEBUG BEGIN: New:- (bsc#1219666, CVE-2023-6597) Add CVE-2023-6597-TempDir-cleaning-symlink.patch (patch from gh#python/cpython!99930) fixing symlink bug in cleanup of BETA DEBUG END: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python311.spec ++++++ --- /var/tmp/diff_new_pack.WGN4vU/_old 2024-03-01 23:36:09.250649599 +0100 +++ /var/tmp/diff_new_pack.WGN4vU/_new 2024-03-01 23:36:09.250649599 +0100 @@ -168,6 +168,9 @@ # PATCH-FIX-UPSTREAM libexpat260.patch gh#python/cpython#115289 # Fix tests for XMLPullParser with Expat 2.6.0 Patch41: libexpat260.patch +# PATCH-FIX-UPSTREAM CVE-2023-6597-TempDir-cleaning-symlink.patch bsc#1219666 mc...@suse.com +# tempfile.TemporaryDirectory: fix symlink bug in cleanup (from gh#python/cpython!99930) +Patch42: CVE-2023-6597-TempDir-cleaning-symlink.patch BuildRequires: autoconf-archive BuildRequires: automake BuildRequires: fdupes @@ -429,6 +432,7 @@ %patch -P 39 -p1 %patch -P 40 -p1 %patch -P 41 -p1 +%patch -P 42 -p1 # drop Autoconf version requirement sed -i 's/^AC_PREREQ/dnl AC_PREREQ/' configure.ac @@ -825,7 +829,6 @@ %dir %{_datadir}/icons/hicolor/32x32 %dir %{_datadir}/icons/hicolor/48x48 %dir %{_datadir}/icons/hicolor/*/apps -%attr(755, root, root) %{_bindir}/idle%{python_version} # endif for if general %endif ++++++ CVE-2023-6597-TempDir-cleaning-symlink.patch ++++++ --- Lib/tempfile.py | 16 + Lib/test/test_tempfile.py | 113 ++++++++++ Misc/NEWS.d/next/Library/2022-12-01-16-57-44.gh-issue-91133.LKMVCV.rst | 2 3 files changed, 131 insertions(+) --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -286,6 +286,22 @@ def _resetperms(path): _dont_follow_symlinks(chflags, path, 0) _dont_follow_symlinks(_os.chmod, path, 0o700) +def _dont_follow_symlinks(func, path, *args): + # Pass follow_symlinks=False, unless not supported on this platform. + if func in _os.supports_follow_symlinks: + func(path, *args, follow_symlinks=False) + elif _os.name == 'nt' or not _os.path.islink(path): + func(path, *args) + +def _resetperms(path): + try: + chflags = _os.chflags + except AttributeError: + pass + else: + _dont_follow_symlinks(chflags, path, 0) + _dont_follow_symlinks(_os.chmod, path, 0o700) + # User visible interfaces. --- a/Lib/test/test_tempfile.py +++ b/Lib/test/test_tempfile.py @@ -1673,6 +1673,103 @@ class TestTemporaryDirectory(BaseTestCas new_flags = os.stat(dir1).st_flags self.assertEqual(new_flags, old_flags) + @os_helper.skip_unless_symlink + def test_cleanup_with_symlink_modes(self): + # cleanup() should not follow symlinks when fixing mode bits (#91133) + with self.do_create(recurse=0) as d2: + file1 = os.path.join(d2, 'file1') + open(file1, 'wb').close() + dir1 = os.path.join(d2, 'dir1') + os.mkdir(dir1) + for mode in range(8): + mode <<= 6 + with self.subTest(mode=format(mode, '03o')): + def test(target, target_is_directory): + d1 = self.do_create(recurse=0) + symlink = os.path.join(d1.name, 'symlink') + os.symlink(target, symlink, + target_is_directory=target_is_directory) + try: + os.chmod(symlink, mode, follow_symlinks=False) + except NotImplementedError: + pass + try: + os.chmod(symlink, mode) + except FileNotFoundError: + pass + os.chmod(d1.name, mode) + d1.cleanup() + self.assertFalse(os.path.exists(d1.name)) + + with self.subTest('nonexisting file'): + test('nonexisting', target_is_directory=False) + with self.subTest('nonexisting dir'): + test('nonexisting', target_is_directory=True) + + with self.subTest('existing file'): + os.chmod(file1, mode) + old_mode = os.stat(file1).st_mode + test(file1, target_is_directory=False) + new_mode = os.stat(file1).st_mode + self.assertEqual(new_mode, old_mode, + '%03o != %03o' % (new_mode, old_mode)) + + with self.subTest('existing dir'): + os.chmod(dir1, mode) + old_mode = os.stat(dir1).st_mode + test(dir1, target_is_directory=True) + new_mode = os.stat(dir1).st_mode + self.assertEqual(new_mode, old_mode, + '%03o != %03o' % (new_mode, old_mode)) + + @unittest.skipUnless(hasattr(os, 'chflags'), 'requires os.chflags') + @os_helper.skip_unless_symlink + def test_cleanup_with_symlink_flags(self): + # cleanup() should not follow symlinks when fixing flags (#91133) + flags = stat.UF_IMMUTABLE | stat.UF_NOUNLINK + self.check_flags(flags) + + with self.do_create(recurse=0) as d2: + file1 = os.path.join(d2, 'file1') + open(file1, 'wb').close() + dir1 = os.path.join(d2, 'dir1') + os.mkdir(dir1) + def test(target, target_is_directory): + d1 = self.do_create(recurse=0) + symlink = os.path.join(d1.name, 'symlink') + os.symlink(target, symlink, + target_is_directory=target_is_directory) + try: + os.chflags(symlink, flags, follow_symlinks=False) + except NotImplementedError: + pass + try: + os.chflags(symlink, flags) + except FileNotFoundError: + pass + os.chflags(d1.name, flags) + d1.cleanup() + self.assertFalse(os.path.exists(d1.name)) + + with self.subTest('nonexisting file'): + test('nonexisting', target_is_directory=False) + with self.subTest('nonexisting dir'): + test('nonexisting', target_is_directory=True) + + with self.subTest('existing file'): + os.chflags(file1, flags) + old_flags = os.stat(file1).st_flags + test(file1, target_is_directory=False) + new_flags = os.stat(file1).st_flags + self.assertEqual(new_flags, old_flags) + + with self.subTest('existing dir'): + os.chflags(dir1, flags) + old_flags = os.stat(dir1).st_flags + test(dir1, target_is_directory=True) + new_flags = os.stat(dir1).st_flags + self.assertEqual(new_flags, old_flags) + @support.cpython_only def test_del_on_collection(self): # A TemporaryDirectory is deleted when garbage collected @@ -1847,6 +1944,22 @@ class TestTemporaryDirectory(BaseTestCas def check_flags(self, flags): # skip the test if these flags are not supported (ex: FreeBSD 13) + filename = os_helper.TESTFN + try: + open(filename, "w").close() + try: + os.chflags(filename, flags) + except OSError as exc: + # "OSError: [Errno 45] Operation not supported" + self.skipTest(f"chflags() doesn't support flags " + f"{flags:#b}: {exc}") + else: + os.chflags(filename, 0) + finally: + os_helper.unlink(filename) + + def check_flags(self, flags): + # skip the test if these flags are not supported (ex: FreeBSD 13) filename = os_helper.TESTFN try: open(filename, "w").close() --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-12-01-16-57-44.gh-issue-91133.LKMVCV.rst @@ -0,0 +1,2 @@ +Fix a bug in :class:`tempfile.TemporaryDirectory` cleanup, which now no longer +dereferences symlinks when working around file system permission errors.