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.

Reply via email to