Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python36 for openSUSE:Factory 
checked in at 2021-02-04 20:21:38
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python36 (Old)
 and      /work/SRC/openSUSE:Factory/.python36.new.28504 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python36"

Thu Feb  4 20:21:38 2021 rev:12 rq:867797 version:3.6.12

Changes:
--------
--- /work/SRC/openSUSE:Factory/python36/python36.changes        2021-01-29 
14:56:51.717488635 +0100
+++ /work/SRC/openSUSE:Factory/.python36.new.28504/python36.changes     
2021-02-04 20:21:40.182606610 +0100
@@ -1,0 +2,7 @@
+Fri Jan 29 17:22:48 UTC 2021 - Matej Cepl <[email protected]>
+
+- Add CVE-2021-3177-buf_ovrfl_PyCArg_repr.patch fixing
+  bsc#1181126 (CVE-2021-3177) buffer overflow in PyCArg_repr in
+  _ctypes/callproc.c, which may lead to remote code execution.
+
+-------------------------------------------------------------------

New:
----
  CVE-2021-3177-buf_ovrfl_PyCArg_repr.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python36.spec ++++++
--- /var/tmp/diff_new_pack.yub4yJ/_old  2021-02-04 20:21:41.366608412 +0100
+++ /var/tmp/diff_new_pack.yub4yJ/_new  2021-02-04 20:21:41.370608419 +0100
@@ -1,5 +1,5 @@
 #
-# spec file for package python36
+# spec file for package python36-core
 #
 # Copyright (c) 2021 SUSE LLC
 #
@@ -174,6 +174,9 @@
 # PATCH-FIX-UPSTREAM CVE-2020-27619-no-eval-http-content.patch bsc#1178009 
[email protected]
 # No longer call eval() on content received via HTTP in the CJK codec tests 
 Patch41:        CVE-2020-27619-no-eval-http-content.patch
+# PATCH-FIX-UPSTREAM CVE-2021-3177-buf_ovrfl_PyCArg_repr.patch bsc#1181126 
[email protected]
+# buffer overflow in PyCArg_repr in _ctypes/callproc.c, which may lead to 
remote code execution
+Patch42:        CVE-2021-3177-buf_ovrfl_PyCArg_repr.patch
 
 BuildRequires:  automake
 BuildRequires:  fdupes
@@ -440,6 +443,7 @@
 %patch39 -p1
 %patch40 -p1
 %patch41 -p1
+%patch42 -p1
 
 # drop Autoconf version requirement
 sed -i 's/^AC_PREREQ/dnl AC_PREREQ/' configure.ac

++++++ CVE-2021-3177-buf_ovrfl_PyCArg_repr.patch ++++++
>From 34df10a9a16b38d54421eeeaf73ec89828563be7 Mon Sep 17 00:00:00 2001
From: Benjamin Peterson <[email protected]>
Date: Mon, 18 Jan 2021 15:11:46 -0600
Subject: [PATCH] [3.6] closes bpo-42938: Replace snprintf with Python unicode
 formatting in ctypes param reprs. (GH-24250)

(cherry picked from commit 916610ef90a0d0761f08747f7b0905541f0977c7)

Co-authored-by: Benjamin Peterson <[email protected]>
---
 Lib/ctypes/test/test_parameters.py            | 43 +++++++++++++++
 .../2021-01-18-09-27-31.bpo-42938.4Zn4Mp.rst  |  2 +
 Modules/_ctypes/callproc.c                    | 55 +++++++------------
 3 files changed, 66 insertions(+), 34 deletions(-)
 create mode 100644 
Misc/NEWS.d/next/Security/2021-01-18-09-27-31.bpo-42938.4Zn4Mp.rst

diff --git a/Lib/ctypes/test/test_parameters.py 
b/Lib/ctypes/test/test_parameters.py
index e4c25fd880cef..531894fdec838 100644
--- a/Lib/ctypes/test/test_parameters.py
+++ b/Lib/ctypes/test/test_parameters.py
@@ -201,6 +201,49 @@ def __dict__(self):
         with self.assertRaises(ZeroDivisionError):
             WorseStruct().__setstate__({}, b'foo')
 
+    def test_parameter_repr(self):
+        from ctypes import (
+            c_bool,
+            c_char,
+            c_wchar,
+            c_byte,
+            c_ubyte,
+            c_short,
+            c_ushort,
+            c_int,
+            c_uint,
+            c_long,
+            c_ulong,
+            c_longlong,
+            c_ulonglong,
+            c_float,
+            c_double,
+            c_longdouble,
+            c_char_p,
+            c_wchar_p,
+            c_void_p,
+        )
+        self.assertRegex(repr(c_bool.from_param(True)), r"^<cparam '\?' at 
0x[A-Fa-f0-9]+>$")
+        self.assertEqual(repr(c_char.from_param(97)), "<cparam 'c' ('a')>")
+        self.assertRegex(repr(c_wchar.from_param('a')), r"^<cparam 'u' at 
0x[A-Fa-f0-9]+>$")
+        self.assertEqual(repr(c_byte.from_param(98)), "<cparam 'b' (98)>")
+        self.assertEqual(repr(c_ubyte.from_param(98)), "<cparam 'B' (98)>")
+        self.assertEqual(repr(c_short.from_param(511)), "<cparam 'h' (511)>")
+        self.assertEqual(repr(c_ushort.from_param(511)), "<cparam 'H' (511)>")
+        self.assertRegex(repr(c_int.from_param(20000)), r"^<cparam '[li]' 
\(20000\)>$")
+        self.assertRegex(repr(c_uint.from_param(20000)), r"^<cparam '[LI]' 
\(20000\)>$")
+        self.assertRegex(repr(c_long.from_param(20000)), r"^<cparam '[li]' 
\(20000\)>$")
+        self.assertRegex(repr(c_ulong.from_param(20000)), r"^<cparam '[LI]' 
\(20000\)>$")
+        self.assertRegex(repr(c_longlong.from_param(20000)), r"^<cparam 
'[liq]' \(20000\)>$")
+        self.assertRegex(repr(c_ulonglong.from_param(20000)), r"^<cparam 
'[LIQ]' \(20000\)>$")
+        self.assertEqual(repr(c_float.from_param(1.5)), "<cparam 'f' (1.5)>")
+        self.assertEqual(repr(c_double.from_param(1.5)), "<cparam 'd' (1.5)>")
+        self.assertEqual(repr(c_double.from_param(1e300)), "<cparam 'd' 
(1e+300)>")
+        self.assertRegex(repr(c_longdouble.from_param(1.5)), r"^<cparam ('d' 
\(1.5\)|'g' at 0x[A-Fa-f0-9]+)>$")
+        self.assertRegex(repr(c_char_p.from_param(b'hihi')), "^<cparam 'z' 
\(0x[A-Fa-f0-9]+\)>$")
+        self.assertRegex(repr(c_wchar_p.from_param('hihi')), "^<cparam 'Z' 
\(0x[A-Fa-f0-9]+\)>$")
+        self.assertRegex(repr(c_void_p.from_param(0x12)), r"^<cparam 'P' 
\(0x0*12\)>$")
+
 ################################################################
 
 if __name__ == '__main__':
diff --git a/Misc/NEWS.d/next/Security/2021-01-18-09-27-31.bpo-42938.4Zn4Mp.rst 
b/Misc/NEWS.d/next/Security/2021-01-18-09-27-31.bpo-42938.4Zn4Mp.rst
new file mode 100644
index 0000000000000..7df65a156feab
--- /dev/null
+++ b/Misc/NEWS.d/next/Security/2021-01-18-09-27-31.bpo-42938.4Zn4Mp.rst
@@ -0,0 +1,2 @@
+Avoid static buffers when computing the repr of :class:`ctypes.c_double` and
+:class:`ctypes.c_longdouble` values.
diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c
index d1c190f359108..2bb289bce043f 100644
--- a/Modules/_ctypes/callproc.c
+++ b/Modules/_ctypes/callproc.c
@@ -461,58 +461,47 @@ is_literal_char(unsigned char c)
 static PyObject *
 PyCArg_repr(PyCArgObject *self)
 {
-    char buffer[256];
     switch(self->tag) {
     case 'b':
     case 'B':
-        sprintf(buffer, "<cparam '%c' (%d)>",
+        return PyUnicode_FromFormat("<cparam '%c' (%d)>",
             self->tag, self->value.b);
-        break;
     case 'h':
     case 'H':
-        sprintf(buffer, "<cparam '%c' (%d)>",
+        return PyUnicode_FromFormat("<cparam '%c' (%d)>",
             self->tag, self->value.h);
-        break;
     case 'i':
     case 'I':
-        sprintf(buffer, "<cparam '%c' (%d)>",
+        return PyUnicode_FromFormat("<cparam '%c' (%d)>",
             self->tag, self->value.i);
-        break;
     case 'l':
     case 'L':
-        sprintf(buffer, "<cparam '%c' (%ld)>",
+        return PyUnicode_FromFormat("<cparam '%c' (%ld)>",
             self->tag, self->value.l);
-        break;
 
     case 'q':
     case 'Q':
-        sprintf(buffer,
-#ifdef MS_WIN32
-            "<cparam '%c' (%I64d)>",
-#else
-            "<cparam '%c' (%lld)>",
-#endif
+        return PyUnicode_FromFormat("<cparam '%c' (%lld)>",
             self->tag, self->value.q);
-        break;
     case 'd':
-        sprintf(buffer, "<cparam '%c' (%f)>",
-            self->tag, self->value.d);
-        break;
-    case 'f':
-        sprintf(buffer, "<cparam '%c' (%f)>",
-            self->tag, self->value.f);
-        break;
-
+    case 'f': {
+        PyObject *f = PyFloat_FromDouble((self->tag == 'f') ? self->value.f : 
self->value.d);
+        if (f == NULL) {
+            return NULL;
+        }
+        PyObject *result = PyUnicode_FromFormat("<cparam '%c' (%R)>", 
self->tag, f);
+        Py_DECREF(f);
+        return result;
+    }
     case 'c':
         if (is_literal_char((unsigned char)self->value.c)) {
-            sprintf(buffer, "<cparam '%c' ('%c')>",
+            return PyUnicode_FromFormat("<cparam '%c' ('%c')>",
                 self->tag, self->value.c);
         }
         else {
-            sprintf(buffer, "<cparam '%c' ('\\x%02x')>",
+            return PyUnicode_FromFormat("<cparam '%c' ('\\x%02x')>",
                 self->tag, (unsigned char)self->value.c);
         }
-        break;
 
 /* Hm, are these 'z' and 'Z' codes useful at all?
    Shouldn't they be replaced by the functionality of c_string
@@ -521,22 +510,20 @@ PyCArg_repr(PyCArgObject *self)
     case 'z':
     case 'Z':
     case 'P':
-        sprintf(buffer, "<cparam '%c' (%p)>",
+        return PyUnicode_FromFormat("<cparam '%c' (%p)>",
             self->tag, self->value.p);
         break;
 
     default:
         if (is_literal_char((unsigned char)self->tag)) {
-            sprintf(buffer, "<cparam '%c' at %p>",
-                (unsigned char)self->tag, self);
+            return PyUnicode_FromFormat("<cparam '%c' at %p>",
+                (unsigned char)self->tag, (void *)self);
         }
         else {
-            sprintf(buffer, "<cparam 0x%02x at %p>",
-                (unsigned char)self->tag, self);
+            return PyUnicode_FromFormat("<cparam 0x%02x at %p>",
+                (unsigned char)self->tag, (void *)self);
         }
-        break;
     }
-    return PyUnicode_FromString(buffer);
 }
 
 static PyMemberDef PyCArgType_members[] = {

Reply via email to