--- Begin Message ---
- To: Debian Bug Tracking System <submit@bugs.debian.org>
- Subject: buster-pu: package python2.7/2.7.16-2+deb10u2
- From: Moritz Muehlenhoff <jmm@debian.org>
- Date: Thu, 25 Feb 2021 19:41:10 +0100
- Message-id: <161427847020.218310.18064501829582072467.reportbug@hullmann.westfalen.local>
Package: release.debian.org
Severity: normal
Tags: buster
User: release.debian.org@packages.debian.org
Usertags: pu
X-Debbugs-Cc: doko@debian.org
debdiff below fixes three security issues, which don't warrant a DSA by itself.
Update has been tested on a Buster few systems (and verified with the PoCs).
Cheers,
Moritz
diff -u python2.7-2.7.16/debian/changelog python2.7-2.7.16/debian/changelog
--- python2.7-2.7.16/debian/changelog
+++ python2.7-2.7.16/debian/changelog
@@ -1,3 +1,11 @@
+python2.7 (2.7.16-2+deb10u2) buster; urgency=medium
+
+ * CVE-2020-8492 (Closes: #970099)
+ * CVE-2019-20907 (Closes: #970099)
+ * CVE-2021-3177
+
+ -- Moritz Mühlenhoff <jmm@debian.org> Wed, 24 Feb 2021 20:33:20 +0200
+
python2.7 (2.7.16-2+deb10u1) buster; urgency=medium
* CVE-2018-20852
diff -u python2.7-2.7.16/debian/patches/series.in python2.7-2.7.16/debian/patches/series.in
--- python2.7-2.7.16/debian/patches/series.in
+++ python2.7-2.7.16/debian/patches/series.in
@@ -80,0 +81,3 @@
+CVE-2019-20907.diff
+CVE-2020-8492.diff
+CVE-2021-3177.diff
only in patch2:
unchanged:
--- python2.7-2.7.16.orig/debian/patches/CVE-2019-20907.diff
+++ python2.7-2.7.16/debian/patches/CVE-2019-20907.diff
@@ -0,0 +1,26 @@
+From 47a2955589bdb1a114d271496ff803ad73f954b8 Mon Sep 17 00:00:00 2001
+From: "Miss Islington (bot)"
+ <31488909+miss-islington@users.noreply.github.com>
+Date: Wed, 15 Jul 2020 05:36:36 -0700
+Subject: [PATCH] bpo-39017: Avoid infinite loop in the tarfile module
+ (GH-21454) (#21485)
+
+Avoid infinite loop when reading specially crafted TAR files using the tarfile module
+(CVE-2019-20907).
+(cherry picked from commit 5a8d121a1f3ef5ad7c105ee378cc79a3eac0c7d4)
+
+Co-authored-by: Rishi <rishi_devan@mail.com>
+
+diff --git a/Lib/tarfile.py b/Lib/tarfile.py
+index adf91d5..574a6bb 100644
+--- a/Lib/tarfile.py
++++ b/Lib/tarfile.py
+@@ -1400,6 +1400,8 @@ class TarInfo(object):
+
+ length, keyword = match.groups()
+ length = int(length)
++ if length == 0:
++ raise InvalidHeaderError("invalid header")
+ value = buf[match.end(2) + 1:match.start(1) + length - 1]
+
+ keyword = keyword.decode("utf8")
only in patch2:
unchanged:
--- python2.7-2.7.16.orig/debian/patches/CVE-2020-8492.diff
+++ python2.7-2.7.16/debian/patches/CVE-2020-8492.diff
@@ -0,0 +1,26 @@
+Backport of 0b297d4ff1c0e4480ad33acae793fbaf4bf015b4, trimmed down to the
+fix for CVE-2020-8492
+
+Co-Authored-By: Serhiy Storchaka <storchaka@gmail.com>
+diff --git a/Lib/urllib2.py b/Lib/urllib2.py
+index 8b634ad..11a62a4 100644
+--- a/Lib/urllib2.py
++++ b/Lib/urllib2.py
+@@ -856,8 +856,15 @@ class AbstractBasicAuthHandler:
+
+ # allow for double- and single-quoted realm values
+ # (single quotes are a violation of the RFC, but appear in the wild)
+- rx = re.compile('(?:.*,)*[ \t]*([^ \t]+)[ \t]+'
+- 'realm=(["\']?)([^"\']*)\\2', re.I)
++ rx = re.compile('(?:^|,)' # start of the string or ','
++ '[ \t]*' # optional whitespaces
++ '([^ \t]+)' # scheme like "Basic"
++ '[ \t]+' # mandatory whitespaces
++ # realm=xxx
++ # realm='xxx'
++ # realm="xxx"
++ 'realm=(["\']?)([^"\']*)\\2',
++ re.I)
+
+ # XXX could pre-emptively send auth info already accepted (RFC 2617,
+ # end of section 2, and section 1.2 immediately after "credentials"
only in patch2:
unchanged:
--- python2.7-2.7.16.orig/debian/patches/CVE-2021-3177.diff
+++ python2.7-2.7.16/debian/patches/CVE-2021-3177.diff
@@ -0,0 +1,149 @@
+bpo-42938: Replace snprintf with Python unicode formatting in ctypes param reprs.
+--- a/Lib/ctypes/test/test_parameters.py
++++ b/Lib/ctypes/test/test_parameters.py
+@@ -206,6 +206,49 @@
+ 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.assertRegexpMatches(repr(c_bool.from_param(True)), r"^<cparam '\?' at 0x[A-Fa-f0-9]+>$")
++ self.assertEqual(repr(c_char.from_param('a')), "<cparam 'c' (a)>")
++ self.assertRegexpMatches(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.assertRegexpMatches(repr(c_int.from_param(20000)), r"^<cparam '[li]' \(20000\)>$")
++ self.assertRegexpMatches(repr(c_uint.from_param(20000)), r"^<cparam '[LI]' \(20000\)>$")
++ self.assertRegexpMatches(repr(c_long.from_param(20000)), r"^<cparam '[li]' \(20000\)>$")
++ self.assertRegexpMatches(repr(c_ulong.from_param(20000)), r"^<cparam '[LI]' \(20000\)>$")
++ self.assertRegexpMatches(repr(c_longlong.from_param(20000)), r"^<cparam '[liq]' \(20000\)>$")
++ self.assertRegexpMatches(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.assertRegexpMatches(repr(c_longdouble.from_param(1.5)), r"^<cparam ('d' \(1.5\)|'g' at 0x[A-Fa-f0-9]+)>$")
++ self.assertRegexpMatches(repr(c_char_p.from_param(b'hihi')), "^<cparam 'z' \(0x[A-Fa-f0-9]+\)>$")
++ self.assertRegexpMatches(repr(c_wchar_p.from_param('hihi')), "^<cparam 'Z' \(0x[A-Fa-f0-9]+\)>$")
++ self.assertRegexpMatches(repr(c_void_p.from_param(0x12)), r"^<cparam 'P' \(0x0*12\)>$")
++
+ ################################################################
+
+ if __name__ == '__main__':
+--- a/Modules/_ctypes/callproc.c
++++ b/Modules/_ctypes/callproc.c
+@@ -460,50 +460,53 @@
+ static PyObject *
+ PyCArg_repr(PyCArgObject *self)
+ {
+- char buffer[256];
+ switch(self->tag) {
+ case 'b':
+ case 'B':
+- sprintf(buffer, "<cparam '%c' (%d)>",
++ return PyString_FromFormat("<cparam '%c' (%d)>",
+ self->tag, self->value.b);
+- break;
+ case 'h':
+ case 'H':
+- sprintf(buffer, "<cparam '%c' (%d)>",
++ return PyString_FromFormat("<cparam '%c' (%d)>",
+ self->tag, self->value.h);
+- break;
+ case 'i':
+ case 'I':
+- sprintf(buffer, "<cparam '%c' (%d)>",
++ return PyString_FromFormat("<cparam '%c' (%d)>",
+ self->tag, self->value.i);
+- break;
+ case 'l':
+ case 'L':
+- sprintf(buffer, "<cparam '%c' (%ld)>",
++ return PyString_FromFormat("<cparam '%c' (%ld)>",
+ self->tag, self->value.l);
+- break;
+
+ #ifdef HAVE_LONG_LONG
+ case 'q':
+ case 'Q':
+- sprintf(buffer,
+- "<cparam '%c' (%" PY_FORMAT_LONG_LONG "d)>",
++ return PyString_FromFormat("<cparam '%c' (%" PY_FORMAT_LONG_LONG "d)>",
+ self->tag, self->value.q);
+- break;
+ #endif
+ 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 *r = PyObject_Repr(f);
++ Py_DECREF(f);
++ if (r == NULL) {
++ return NULL;
++ }
++ char *value = PyString_AsString(r);
++ Py_DECREF(r);
++ if (value == NULL) {
++ return NULL;
++ }
++ return PyString_FromFormat("<cparam '%c' (%s)>",
++ self->tag, value);
++ }
+
+ case 'c':
+- sprintf(buffer, "<cparam '%c' (%c)>",
++ return PyString_FromFormat("<cparam '%c' (%c)>",
+ self->tag, 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
+@@ -512,16 +515,13 @@
+ case 'z':
+ case 'Z':
+ case 'P':
+- sprintf(buffer, "<cparam '%c' (%p)>",
++ return PyString_FromFormat("<cparam '%c' (%p)>",
+ self->tag, self->value.p);
+- break;
+
+ default:
+- sprintf(buffer, "<cparam '%c' at %p>",
++ return PyString_FromFormat("<cparam '%c' at %p>",
+ self->tag, self);
+- break;
+ }
+- return PyString_FromString(buffer);
+ }
+
+ static PyMemberDef PyCArgType_members[] = {
--- End Message ---