SHA256
1
0

Accepting request 1153186 from devel:languages:python:Factory

- (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.
- Remove double definition of /usr/bin/idle%%{version} in
  %%files.

OBS-URL: https://build.opensuse.org/request/show/1153186
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/python311?expand=0&rev=30
This commit is contained in:
Dominique Leuenberger 2024-03-01 22:35:58 +00:00 committed by Git OBS Bridge
commit d0d6107118
3 changed files with 183 additions and 1 deletions

View File

@ -0,0 +1,165 @@
---
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.

View File

@ -1,3 +1,17 @@
-------------------------------------------------------------------
Fri Feb 23 01:06:42 UTC 2024 - Matej Cepl <mcepl@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 <mcepl@cepl.eu>
- Remove double definition of /usr/bin/idle%%{version} in
%%files.
-------------------------------------------------------------------
Thu Feb 15 10:29:07 UTC 2024 - Daniel Garcia <daniel.garcia@suse.com>

View File

@ -168,6 +168,9 @@ Patch40: CVE-2023-27043-email-parsing-errors.patch
# 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 mcepl@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 @@ other applications.
%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 @@ echo %{sitedir}/_import_failed > %{buildroot}/%{sitedir}/site-packages/zzzz-impo
%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