]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] Revert "gh-119452: Fix a potential virtual memory allocation denial of service...
authorHugo van Kemenade <1324225+hugovk@users.noreply.github.com>
Tue, 2 Dec 2025 12:04:25 +0000 (14:04 +0200)
committerGitHub <noreply@github.com>
Tue, 2 Dec 2025 12:04:25 +0000 (12:04 +0000)
Revert "[3.13] gh-119452: Fix a potential virtual memory allocation denial of service in http.server (GH-119455) (GH-142130)"

This reverts commit 6c922bbe28f2cd901ffa749240f96449287771a6.

Lib/http/server.py
Lib/test/test_httpservers.py
Misc/NEWS.d/next/Security/2024-05-23-11-44-41.gh-issue-119452.PRfsSv.rst [deleted file]

index f9d676c8eb1861a7f2f334130dd7f459c6443e43..758a725f1fd540741e9b9c679af196796a48b84b 100644 (file)
@@ -127,10 +127,6 @@ DEFAULT_ERROR_MESSAGE = """\
 
 DEFAULT_ERROR_CONTENT_TYPE = "text/html;charset=utf-8"
 
-# Data larger than this will be read in chunks, to prevent extreme
-# overallocation.
-_MIN_READ_BUF_SIZE = 1 << 20
-
 class HTTPServer(socketserver.TCPServer):
 
     allow_reuse_address = 1    # Seems to make sense in testing environment
@@ -1238,16 +1234,7 @@ class CGIHTTPRequestHandler(SimpleHTTPRequestHandler):
                                  env = env
                                  )
             if self.command.lower() == "post" and nbytes > 0:
-                cursize = 0
-                data = self.rfile.read(min(nbytes, _MIN_READ_BUF_SIZE))
-                while (len(data) < nbytes and len(data) != cursize and
-                       select.select([self.rfile._sock], [], [], 0)[0]):
-                    cursize = len(data)
-                    # This is a geometric increase in read size (never more
-                    # than doubling our the current length of data per loop
-                    # iteration).
-                    delta = min(cursize, nbytes - cursize)
-                    data += self.rfile.read(delta)
+                data = self.rfile.read(nbytes)
             else:
                 data = None
             # throw away additional data [see bug #427345]
index 9e69f6f6d75dec96faa82ce28f6ca960bc147c30..c369baf28fe823153cb67c7f9e15896813dceac2 100644 (file)
@@ -802,20 +802,6 @@ for k, v in os.environ.items():
 print("</pre>")
 """
 
-cgi_file7 = """\
-#!%s
-import os
-import sys
-
-print("Content-type: text/plain")
-print()
-
-content_length = int(os.environ["CONTENT_LENGTH"])
-body = sys.stdin.buffer.read(content_length)
-
-print(f"{content_length} {len(body)}")
-"""
-
 
 @unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0,
         "This test can't be run reliably as root (issue #13308).")
@@ -855,8 +841,6 @@ class CGIHTTPServerTestCase(BaseTestCase):
         self.file3_path = None
         self.file4_path = None
         self.file5_path = None
-        self.file6_path = None
-        self.file7_path = None
 
         # The shebang line should be pure ASCII: use symlink if possible.
         # See issue #7668.
@@ -911,11 +895,6 @@ class CGIHTTPServerTestCase(BaseTestCase):
             file6.write(cgi_file6 % self.pythonexe)
         os.chmod(self.file6_path, 0o777)
 
-        self.file7_path = os.path.join(self.cgi_dir, 'file7.py')
-        with open(self.file7_path, 'w', encoding='utf-8') as file7:
-            file7.write(cgi_file7 % self.pythonexe)
-        os.chmod(self.file7_path, 0o777)
-
         os.chdir(self.parent_dir)
 
     def tearDown(self):
@@ -938,8 +917,6 @@ class CGIHTTPServerTestCase(BaseTestCase):
                 os.remove(self.file5_path)
             if self.file6_path:
                 os.remove(self.file6_path)
-            if self.file7_path:
-                os.remove(self.file7_path)
             os.rmdir(self.cgi_child_dir)
             os.rmdir(self.cgi_dir)
             os.rmdir(self.cgi_dir_in_sub_dir)
@@ -1012,21 +989,6 @@ class CGIHTTPServerTestCase(BaseTestCase):
 
         self.assertEqual(res.read(), b'1, python, 123456' + self.linesep)
 
-    def test_large_content_length(self):
-        for w in range(15, 25):
-            size = 1 << w
-            body = b'X' * size
-            headers = {'Content-Length' : str(size)}
-            res = self.request('/cgi-bin/file7.py', 'POST', body, headers)
-            self.assertEqual(res.read(), b'%d %d' % (size, size) + self.linesep)
-
-    def test_large_content_length_truncated(self):
-        for w in range(18, 65):
-            size = 1 << w
-            headers = {'Content-Length' : str(size)}
-            res = self.request('/cgi-bin/file1.py', 'POST', b'x', headers)
-            self.assertEqual(res.read(), b'Hello World' + self.linesep)
-
     def test_invaliduri(self):
         res = self.request('/cgi-bin/invalid')
         res.read()
diff --git a/Misc/NEWS.d/next/Security/2024-05-23-11-44-41.gh-issue-119452.PRfsSv.rst b/Misc/NEWS.d/next/Security/2024-05-23-11-44-41.gh-issue-119452.PRfsSv.rst
deleted file mode 100644 (file)
index 9895662..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-Fix a potential memory denial of service in the :mod:`http.server` module.
-When a malicious user is connected to the CGI server on Windows, it could cause
-an arbitrary amount of memory to be allocated.
-This could have led to symptoms including a :exc:`MemoryError`, swapping, out
-of memory (OOM) killed processes or containers, or even system crashes.