-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
336 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,9 @@ | ||
untrusted comment: verify with /etc/ports/opt-arm.pub | ||
RWQh9Dk2FlLauMI4APoZtNFP+U0334i4w06Cihb0GUf4ikHepzhp6dzRZMiGe0h7JIUpkmbJtWQ/PstCTAb6eG/IB+WlLi+t2gg= | ||
SHA256 (Pkgfile) = 279e9ac499489587cdbf42a9af392495023e8fc40f2f8dbb13bf0bb21a29756f | ||
SHA256 (.footprint) = a20c7204cf8035ad40a6d21486ddcb068b38bf1b069bc5631969acdb04e20aa6 | ||
RWQh9Dk2FlLauJTEbTLVjeYUVOnFW1i+dIPyQ1HMPKHQOH98lxuckEd3a4jBhfAc4Z11hXrvsgYB7pvqRnD263vqVwX4kvcZJQ8= | ||
SHA256 (Pkgfile) = 825e890388962ed122b50243f1039b6423ef144a9afba132a506ee088ed2a684 | ||
SHA256 (.footprint) = 1ee5fb8f3e3d2cc9fd8e8240c7c8f25949cdc133ac1f859c0c52c9675d6967c6 | ||
SHA256 (Python-2.7.18.tar.xz) = b62c0e7937551d0cc02b8fd5cb0f544f9405bafc9a54d3808ed4594812edef43 | ||
SHA256 (pyconfig.h) = 081426cb9524c2e156a71bb035c25a67e44d389afc6f7e091bcf86a7f4e2002f | ||
SHA256 (CVE-2019-20907.patch) = 59f8039b26f6a4613847fb4b30a1da612b4c0d5ed3c1cc92f498ebd71a734b04 | ||
SHA256 (CVE-2020-26116.patch) = 290f34ab3e6cdd99fff00ab7b1e01d3e9c4acc36ecb87b7db76207c4cdaf692a | ||
SHA256 (CVE-2021-3177.patch) = db7835b3fa3a2897e531a219127a02bbc902e31f3363f27a456a45ddbb4eca31 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||
From: Rishi <rishi_devan@mail.com> | ||
Date: Wed, 15 Jul 2020 13:51:00 +0200 | ||
Subject: [PATCH] 00351-cve-2019-20907-fix-infinite-loop-in-tarfile.patch | ||
|
||
00351 # | ||
Avoid infinite loop when reading specially crafted TAR files using the tarfile module | ||
(CVE-2019-20907). | ||
See: https://bugs.python.org/issue39017 | ||
--- | ||
Lib/tarfile.py | 2 ++ | ||
|
||
diff --git a/Lib/tarfile.py b/Lib/tarfile.py | ||
index adf91d53823..574a6bb279d 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") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||
From: AMIR <31338382+amiremohamadi@users.noreply.github.com> | ||
Date: Sun, 19 Jul 2020 00:46:10 +0430 | ||
Subject: [PATCH] | ||
00354-cve-2020-26116-http-request-method-crlf-injection-in-httplib.patch | ||
|
||
00354 # | ||
Reject control chars in HTTP method in httplib.putrequest to prevent | ||
HTTP header injection | ||
|
||
Backported from Python 3.5-3.10 (and adjusted for py2's single-module httplib): | ||
- https://bugs.python.org/issue39603 | ||
- https://github.com/python/cpython/pull/18485 (3.10) | ||
- https://github.com/python/cpython/pull/21946 (3.5) | ||
|
||
Co-authored-by: AMIR <31338382+amiremohamadi@users.noreply.github.com> | ||
--- | ||
Lib/httplib.py | 16 +++++++++++++ | ||
Lib/test/test_httplib.py | 23 +++++++++++++++++++ | ||
.../2020-02-12-14-17-39.bpo-39603.Gt3RSg.rst | 2 ++ | ||
3 files changed, 41 insertions(+) | ||
create mode 100644 Misc/NEWS.d/next/Security/2020-02-12-14-17-39.bpo-39603.Gt3RSg.rst | ||
|
||
diff --git a/Lib/httplib.py b/Lib/httplib.py | ||
index fcc4152aaf2..a63677477d5 100644 | ||
--- a/Lib/httplib.py | ||
+++ b/Lib/httplib.py | ||
@@ -257,6 +257,10 @@ _contains_disallowed_url_pchar_re = re.compile('[\x00-\x20\x7f-\xff]') | ||
# _is_allowed_url_pchars_re = re.compile(r"^[/!$&'()*+,;=:@%a-zA-Z0-9._~-]+$") | ||
# We are more lenient for assumed real world compatibility purposes. | ||
|
||
+# These characters are not allowed within HTTP method names | ||
+# to prevent http header injection. | ||
+_contains_disallowed_method_pchar_re = re.compile('[\x00-\x1f]') | ||
+ | ||
# We always set the Content-Length header for these methods because some | ||
# servers will otherwise respond with a 411 | ||
_METHODS_EXPECTING_BODY = {'PATCH', 'POST', 'PUT'} | ||
@@ -935,6 +939,8 @@ class HTTPConnection: | ||
else: | ||
raise CannotSendRequest() | ||
|
||
+ self._validate_method(method) | ||
+ | ||
# Save the method for use later in the response phase | ||
self._method = method | ||
|
||
@@ -1020,6 +1026,16 @@ class HTTPConnection: | ||
# On Python 2, request is already encoded (default) | ||
return request | ||
|
||
+ def _validate_method(self, method): | ||
+ """Validate a method name for putrequest.""" | ||
+ # prevent http header injection | ||
+ match = _contains_disallowed_method_pchar_re.search(method) | ||
+ if match: | ||
+ raise ValueError( | ||
+ "method can't contain control characters. %r " | ||
+ "(found at least %r)" | ||
+ % (method, match.group())) | ||
+ | ||
def _validate_path(self, url): | ||
"""Validate a url for putrequest.""" | ||
# Prevent CVE-2019-9740. | ||
diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py | ||
index d8a57f73530..e295bb796ec 100644 | ||
--- a/Lib/test/test_httplib.py | ||
+++ b/Lib/test/test_httplib.py | ||
@@ -385,6 +385,28 @@ class HeaderTests(TestCase): | ||
conn.putheader(name, value) | ||
|
||
|
||
+class HttpMethodTests(TestCase): | ||
+ def test_invalid_method_names(self): | ||
+ methods = ( | ||
+ 'GET\r', | ||
+ 'POST\n', | ||
+ 'PUT\n\r', | ||
+ 'POST\nValue', | ||
+ 'POST\nHOST:abc', | ||
+ 'GET\nrHost:abc\n', | ||
+ 'POST\rRemainder:\r', | ||
+ 'GET\rHOST:\n', | ||
+ '\nPUT' | ||
+ ) | ||
+ | ||
+ for method in methods: | ||
+ with self.assertRaisesRegexp( | ||
+ ValueError, "method can't contain control characters"): | ||
+ conn = httplib.HTTPConnection('example.com') | ||
+ conn.sock = FakeSocket(None) | ||
+ conn.request(method=method, url="/") | ||
+ | ||
+ | ||
class BasicTest(TestCase): | ||
def test_status_lines(self): | ||
# Test HTTP status lines | ||
@@ -1010,6 +1032,7 @@ class TunnelTests(TestCase): | ||
@test_support.reap_threads | ||
def test_main(verbose=None): | ||
test_support.run_unittest(HeaderTests, OfflineTest, BasicTest, TimeoutTest, | ||
+ HttpMethodTests, | ||
HTTPTest, HTTPSTest, SourceAddressTest, | ||
TunnelTests) | ||
|
||
diff --git a/Misc/NEWS.d/next/Security/2020-02-12-14-17-39.bpo-39603.Gt3RSg.rst b/Misc/NEWS.d/next/Security/2020-02-12-14-17-39.bpo-39603.Gt3RSg.rst | ||
new file mode 100644 | ||
index 00000000000..990affc3edd | ||
--- /dev/null | ||
+++ b/Misc/NEWS.d/next/Security/2020-02-12-14-17-39.bpo-39603.Gt3RSg.rst | ||
@@ -0,0 +1,2 @@ | ||
+Prevent http header injection by rejecting control characters in | ||
+http.client.putrequest(...). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||
From: Petr Viktorin <pviktori@redhat.com> | ||
Date: Mon, 1 Feb 2021 19:29:17 +0100 | ||
Subject: [PATCH] 00357-CVE-2021-3177.patch | ||
|
||
00357 # | ||
CVE-2021-3177: Replace snprintf with Python unicode formatting in ctypes param reprs | ||
|
||
Backport of Python3 commit 916610ef90a0d0761f08747f7b0905541f0977c7: | ||
https://bugs.python.org/issue42938 | ||
https://github.com/python/cpython/pull/24239 | ||
--- | ||
Lib/ctypes/test/test_parameters.py | 43 ++++++++++++++++++++ | ||
Modules/_ctypes/callproc.c | 65 +++++++++++++++++------------- | ||
2 files changed, 80 insertions(+), 28 deletions(-) | ||
|
||
diff --git a/Lib/ctypes/test/test_parameters.py b/Lib/ctypes/test/test_parameters.py | ||
index 23c1b6e2259..77300d71ae1 100644 | ||
--- a/Lib/ctypes/test/test_parameters.py | ||
+++ b/Lib/ctypes/test/test_parameters.py | ||
@@ -206,6 +206,49 @@ class SimpleTypesTestCase(unittest.TestCase): | ||
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__': | ||
diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c | ||
index 066fefc0cca..5cc3c4cf685 100644 | ||
--- a/Modules/_ctypes/callproc.c | ||
+++ b/Modules/_ctypes/callproc.c | ||
@@ -460,50 +460,62 @@ PyCArg_dealloc(PyCArgObject *self) | ||
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' (%lld)>", | ||
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 *s = PyString_FromFormat("<cparam '%c' (", self->tag); | ||
+ if (s == NULL) { | ||
+ return NULL; | ||
+ } | ||
+ PyObject *f = PyFloat_FromDouble((self->tag == 'f') ? self->value.f : self->value.d); | ||
+ if (f == NULL) { | ||
+ Py_DECREF(s); | ||
+ return NULL; | ||
+ } | ||
+ PyObject *r = PyObject_Repr(f); | ||
+ Py_DECREF(f); | ||
+ if (r == NULL) { | ||
+ Py_DECREF(s); | ||
+ return NULL; | ||
+ } | ||
+ PyString_ConcatAndDel(&s, r); | ||
+ if (s == NULL) { | ||
+ return NULL; | ||
+ } | ||
+ r = PyString_FromString(")>"); | ||
+ if (r == NULL) { | ||
+ Py_DECREF(s); | ||
+ return NULL; | ||
+ } | ||
+ PyString_ConcatAndDel(&s, r); | ||
+ return s; | ||
+ } | ||
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 +524,13 @@ 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: | ||
- sprintf(buffer, "<cparam '%c' at %p>", | ||
- self->tag, self); | ||
- break; | ||
+ return PyString_FromFormat("<cparam '%c' at %p>", | ||
+ (unsigned char)self->tag, (void *)self); | ||
} | ||
- return PyString_FromString(buffer); | ||
} | ||
|
||
static PyMemberDef PyCArgType_members[] = { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters