[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1111653: marked as done (bookworm-pu: package waitress/2.1.2-2+deb12u1)



Your message dated Sat, 06 Sep 2025 12:14:50 +0100
with message-id <ee4c0876608d99eb3f8b333b556fbd92e7a652eb.camel@adam-barratt.org.uk>
and subject line Closing p-u requests for fixes included in 12.12
has caused the Debian Bug report #1111653,
regarding bookworm-pu: package waitress/2.1.2-2+deb12u1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
1111653: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1111653
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: bookworm
X-Debbugs-Cc: waitress@packages.debian.org, security@debian.org
Control: affects -1 + src:waitress
User: release.debian.org@packages.debian.org
Usertags: pu

  * CVE-2024-49768: race condition in HTTP pipelining
    (Closes: #1086467)
  * CVE-2024-49769: DoS due to resource exhaustion
    (Closes: #1086468)
diffstat for waitress-2.1.2 waitress-2.1.2

 changelog                                                               |   10 
 patches/0001-Fix-a-race-condition-on-recv_bytes-boundary-when-req.patch |   58 +++
 patches/0002-Make-DummySock-look-more-like-an-actual-socket.patch       |  161 ++++++++++
 patches/0003-Add-a-new-test-to-validate-the-lookahead-race-condit.patch |   89 +++++
 patches/0004-Remove-test-for-getpeername.patch                          |   34 ++
 patches/0005-When-closing-the-socket-set-it-to-None.patch               |   40 ++
 patches/0006-Don-t-exit-handle_write-early-even-if-socket-is-not-.patch |   32 +
 patches/0007-Assume-socket-is-not-connected-when-passed-to-wasync.patch |   51 +++
 patches/0008-HTTPChannel-is-always-created-from-accept-explicitly.patch |   27 +
 patches/series                                                          |    8 
 10 files changed, 510 insertions(+)

diff -Nru waitress-2.1.2/debian/changelog waitress-2.1.2/debian/changelog
--- waitress-2.1.2/debian/changelog	2022-11-14 18:15:51.000000000 +0200
+++ waitress-2.1.2/debian/changelog	2025-08-20 18:31:13.000000000 +0300
@@ -1,3 +1,13 @@
+waitress (2.1.2-2+deb12u1) bookworm; urgency=medium
+
+  * Non-maintainer upload.
+  * CVE-2024-49768: race condition in HTTP pipelining
+    (Closes: #1086467)
+  * CVE-2024-49769: DoS due to resource exhaustion
+    (Closes: #1086468)
+
+ -- Adrian Bunk <bunk@debian.org>  Wed, 20 Aug 2025 18:31:13 +0300
+
 waitress (2.1.2-2) unstable; urgency=medium
 
   * Team Upload.
diff -Nru waitress-2.1.2/debian/patches/0001-Fix-a-race-condition-on-recv_bytes-boundary-when-req.patch waitress-2.1.2/debian/patches/0001-Fix-a-race-condition-on-recv_bytes-boundary-when-req.patch
--- waitress-2.1.2/debian/patches/0001-Fix-a-race-condition-on-recv_bytes-boundary-when-req.patch	1970-01-01 02:00:00.000000000 +0200
+++ waitress-2.1.2/debian/patches/0001-Fix-a-race-condition-on-recv_bytes-boundary-when-req.patch	2025-08-20 18:30:00.000000000 +0300
@@ -0,0 +1,58 @@
+From f53910e5463bcd52a0b39c1e7a1759b6ac17dbdf Mon Sep 17 00:00:00 2001
+From: Delta Regeer <bertjw@regeer.org>
+Date: Sat, 26 Oct 2024 22:13:08 -0600
+Subject: Fix a race condition on recv_bytes boundary when request is invalid
+
+A remote client may send a request that is exactly recv_bytes long,
+followed by a secondary request using HTTP pipelining.
+
+When request lookahead is disabled (default) we won't read any more
+requests, and when the first request fails due to a parsing error, we
+simply close the connection.
+
+However when request lookahead is enabled, it is possible to process and
+receive the first request, start sending the error message back to the
+client while we read the next request and queue it. This will allow the
+secondar request to be serviced by the worker thread while the
+connection should be closed.
+
+The fix here checks if we should not have read the data in the first
+place (because the conection is going to be torn down) while we hold the
+`requests_lock` which means the service thread can't be in the middle of
+flipping the `close_when_flushed` flag.
+---
+ src/waitress/channel.py | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/src/waitress/channel.py b/src/waitress/channel.py
+index eb59dd3..756adce 100644
+--- a/src/waitress/channel.py
++++ b/src/waitress/channel.py
+@@ -147,7 +147,7 @@ class HTTPChannel(wasyncore.dispatcher):
+         # 1. We're not already about to close the connection.
+         # 2. We're not waiting to flush remaining data before closing the
+         #    connection
+-        # 3. There are not too many tasks already queued
++        # 3. There are not too many tasks already queued (if lookahead is enabled)
+         # 4. There's no data in the output buffer that needs to be sent
+         #    before we potentially create a new task.
+ 
+@@ -203,6 +203,15 @@ class HTTPChannel(wasyncore.dispatcher):
+             return False
+ 
+         with self.requests_lock:
++            # Don't bother processing anymore data if this connection is about
++            # to close. This may happen if readable() returned True, on the
++            # main thread before the service thread set the close_when_flushed
++            # flag, and we read data but our service thread is attempting to
++            # shut down the connection due to an error. We want to make sure we
++            # do this while holding the request_lock so that we can't race
++            if self.will_close or self.close_when_flushed:
++                return False
++
+             while data:
+                 if self.request is None:
+                     self.request = self.parser_class(self.adj)
+-- 
+2.30.2
+
diff -Nru waitress-2.1.2/debian/patches/0002-Make-DummySock-look-more-like-an-actual-socket.patch waitress-2.1.2/debian/patches/0002-Make-DummySock-look-more-like-an-actual-socket.patch
--- waitress-2.1.2/debian/patches/0002-Make-DummySock-look-more-like-an-actual-socket.patch	1970-01-01 02:00:00.000000000 +0200
+++ waitress-2.1.2/debian/patches/0002-Make-DummySock-look-more-like-an-actual-socket.patch	2025-08-20 18:30:00.000000000 +0300
@@ -0,0 +1,161 @@
+From 264eb0ddeea74175d9e5e53028202500bd8cb6ad Mon Sep 17 00:00:00 2001
+From: Delta Regeer <bertjw@regeer.org>
+Date: Sat, 26 Oct 2024 22:10:36 -0600
+Subject: Make DummySock() look more like an actual socket
+
+This forces DummySock() to look like a properly connected socket where
+there is a buffer that is read from by the remote, and a buffer that is
+written to by the remote.
+
+The local side does the opposite, this way data written by the local
+side can be read by the remote without operating on the same buffer.
+---
+ tests/test_channel.py | 57 +++++++++++++++++++++++++++++++++----------
+ 1 file changed, 44 insertions(+), 13 deletions(-)
+
+diff --git a/tests/test_channel.py b/tests/test_channel.py
+index 8467ae7..7d677e9 100644
+--- a/tests/test_channel.py
++++ b/tests/test_channel.py
+@@ -18,7 +18,7 @@ class TestHTTPChannel(unittest.TestCase):
+         map = {}
+         inst = self._makeOne(sock, "127.0.0.1", adj, map=map)
+         inst.outbuf_lock = DummyLock()
+-        return inst, sock, map
++        return inst, sock.local(), map
+ 
+     def test_ctor(self):
+         inst, _, map = self._makeOneWithMap()
+@@ -218,7 +218,7 @@ class TestHTTPChannel(unittest.TestCase):
+         def send(_):
+             return 0
+ 
+-        sock.send = send
++        sock.remote.send = send
+ 
+         wrote = inst.write_soon(b"a")
+         self.assertEqual(wrote, 1)
+@@ -236,7 +236,7 @@ class TestHTTPChannel(unittest.TestCase):
+         def send(_):
+             return 0
+ 
+-        sock.send = send
++        sock.remote.send = send
+ 
+         outbufs = inst.outbufs
+         wrote = inst.write_soon(wrapper)
+@@ -270,7 +270,7 @@ class TestHTTPChannel(unittest.TestCase):
+         def send(_):
+             return 0
+ 
+-        sock.send = send
++        sock.remote.send = send
+ 
+         inst.adj.outbuf_high_watermark = 3
+         inst.current_outbuf_count = 4
+@@ -286,7 +286,7 @@ class TestHTTPChannel(unittest.TestCase):
+         def send(_):
+             return 0
+ 
+-        sock.send = send
++        sock.remote.send = send
+ 
+         inst.adj.outbuf_high_watermark = 3
+         inst.total_outbufs_len = 4
+@@ -315,7 +315,7 @@ class TestHTTPChannel(unittest.TestCase):
+             inst.connected = False
+             raise Exception()
+ 
+-        sock.send = send
++        sock.remote.send = send
+ 
+         inst.adj.outbuf_high_watermark = 3
+         inst.total_outbufs_len = 4
+@@ -345,7 +345,7 @@ class TestHTTPChannel(unittest.TestCase):
+             inst.connected = False
+             raise Exception()
+ 
+-        sock.send = send
++        sock.remote.send = send
+ 
+         wrote = inst.write_soon(b"xyz")
+         self.assertEqual(wrote, 3)
+@@ -376,7 +376,7 @@ class TestHTTPChannel(unittest.TestCase):
+         inst.total_outbufs_len = len(inst.outbufs[0])
+         inst.adj.send_bytes = 1
+         inst.adj.outbuf_high_watermark = 2
+-        sock.send = lambda x, do_close=True: False
++        sock.remote.send = lambda x, do_close=True: False
+         inst.will_close = False
+         inst.last_activity = 0
+         result = inst.handle_write()
+@@ -400,7 +400,7 @@ class TestHTTPChannel(unittest.TestCase):
+ 
+     def test__flush_some_full_outbuf_socket_returns_zero(self):
+         inst, sock, map = self._makeOneWithMap()
+-        sock.send = lambda x: False
++        sock.remote.send = lambda x: False
+         inst.outbufs[0].append(b"abc")
+         inst.total_outbufs_len = sum(len(x) for x in inst.outbufs)
+         result = inst._flush_some()
+@@ -907,7 +907,8 @@ class DummySock:
+     closed = False
+ 
+     def __init__(self):
+-        self.sent = b""
++        self.local_sent = b""
++        self.remote_sent = b""
+ 
+     def setblocking(self, *arg):
+         self.blocking = True
+@@ -925,14 +926,44 @@ class DummySock:
+         self.closed = True
+ 
+     def send(self, data):
+-        self.sent += data
++        self.remote_sent += data
+         return len(data)
+ 
+     def recv(self, buffer_size):
+-        result = self.sent[:buffer_size]
+-        self.sent = self.sent[buffer_size:]
++        result = self.local_sent[:buffer_size]
++        self.local_sent = self.local_sent[buffer_size:]
+         return result
+ 
++    def local(self):
++        outer = self
++
++        class LocalDummySock:
++            def send(self, data):
++                outer.local_sent += data
++                return len(data)
++
++            def recv(self, buffer_size):
++                result = outer.remote_sent[:buffer_size]
++                outer.remote_sent = outer.remote_sent[buffer_size:]
++                return result
++
++            def close(self):
++                outer.closed = True
++
++            @property
++            def sent(self):
++                return outer.remote_sent
++
++            @property
++            def closed(self):
++                return outer.closed
++
++            @property
++            def remote(self):
++                return outer
++
++        return LocalDummySock()
++
+ 
+ class DummyLock:
+     notified = False
+-- 
+2.30.2
+
diff -Nru waitress-2.1.2/debian/patches/0003-Add-a-new-test-to-validate-the-lookahead-race-condit.patch waitress-2.1.2/debian/patches/0003-Add-a-new-test-to-validate-the-lookahead-race-condit.patch
--- waitress-2.1.2/debian/patches/0003-Add-a-new-test-to-validate-the-lookahead-race-condit.patch	1970-01-01 02:00:00.000000000 +0200
+++ waitress-2.1.2/debian/patches/0003-Add-a-new-test-to-validate-the-lookahead-race-condit.patch	2025-08-20 18:30:00.000000000 +0300
@@ -0,0 +1,89 @@
+From 72176921186f2fca1318321785c0328d4ba5d805 Mon Sep 17 00:00:00 2001
+From: Delta Regeer <bertjw@regeer.org>
+Date: Sat, 26 Oct 2024 22:12:14 -0600
+Subject: Add a new test to validate the lookahead race condition
+
+---
+ tests/test_channel.py | 55 ++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 54 insertions(+), 1 deletion(-)
+
+diff --git a/tests/test_channel.py b/tests/test_channel.py
+index 7d677e9..d798091 100644
+--- a/tests/test_channel.py
++++ b/tests/test_channel.py
+@@ -805,11 +805,12 @@ class TestHTTPChannelLookahead(TestHTTPChannel):
+         )
+         return [body]
+ 
+-    def _make_app_with_lookahead(self):
++    def _make_app_with_lookahead(self, recv_bytes=8192):
+         """
+         Setup a channel with lookahead and store it and the socket in self
+         """
+         adj = DummyAdjustments()
++        adj.recv_bytes = recv_bytes
+         adj.channel_request_lookahead = 5
+         channel, sock, map = self._makeOneWithMap(adj=adj)
+         channel.server.application = self.app_check_disconnect
+@@ -901,6 +902,58 @@ class TestHTTPChannelLookahead(TestHTTPChannel):
+         self.assertEqual(data.split("\r\n")[-1], "finished")
+         self.assertEqual(self.request_body, b"x")
+ 
++    def test_lookahead_bad_request_drop_extra_data(self):
++        """
++        Send two requests, the first one being bad, split on the recv_bytes
++        limit, then emulate a race that could happen whereby we read data from
++        the socket while the service thread is cleaning up due to an error
++        processing the request.
++        """
++
++        invalid_request = [
++            "GET / HTTP/1.1",
++            "Host: localhost:8080",
++            "Content-length: -1",
++            "",
++        ]
++
++        invalid_request_len = len("".join([x + "\r\n" for x in invalid_request]))
++
++        second_request = [
++            "POST / HTTP/1.1",
++            "Host: localhost:8080",
++            "Content-Length: 1",
++            "",
++            "x",
++        ]
++
++        full_request = invalid_request + second_request
++
++        self._make_app_with_lookahead(recv_bytes=invalid_request_len)
++        self._send(*full_request)
++        self.channel.handle_read()
++        self.assertEqual(len(self.channel.requests), 1)
++        self.channel.server.tasks[0].service()
++        self.assertTrue(self.channel.close_when_flushed)
++        # Read all of the next request
++        self.channel.handle_read()
++        self.channel.handle_read()
++        # Validate that there is no more data to be read
++        self.assertEqual(self.sock.remote.local_sent, b"")
++        # Validate that we dropped the data from the second read, and did not
++        # create a new request
++        self.assertEqual(len(self.channel.requests), 0)
++        data = self.sock.recv(256).decode("ascii")
++        self.assertFalse(self.channel.readable())
++        self.assertTrue(self.channel.writable())
++
++        # Handle the write, which will close the socket
++        self.channel.handle_write()
++        self.assertTrue(self.sock.closed)
++
++        data = self.sock.recv(256)
++        self.assertEqual(len(data), 0)
++
+ 
+ class DummySock:
+     blocking = False
+-- 
+2.30.2
+
diff -Nru waitress-2.1.2/debian/patches/0004-Remove-test-for-getpeername.patch waitress-2.1.2/debian/patches/0004-Remove-test-for-getpeername.patch
--- waitress-2.1.2/debian/patches/0004-Remove-test-for-getpeername.patch	1970-01-01 02:00:00.000000000 +0200
+++ waitress-2.1.2/debian/patches/0004-Remove-test-for-getpeername.patch	2025-08-20 18:30:00.000000000 +0300
@@ -0,0 +1,34 @@
+From 8ef9217ae753cbce02c6553c389299f6c82352b2 Mon Sep 17 00:00:00 2001
+From: Delta Regeer <bertjw@regeer.org>
+Date: Sun, 3 Mar 2024 16:23:33 -0700
+Subject: Remove test for getpeername()
+
+---
+ tests/test_wasyncore.py | 11 -----------
+ 1 file changed, 11 deletions(-)
+
+diff --git a/tests/test_wasyncore.py b/tests/test_wasyncore.py
+index e833c7e..5f38bd9 100644
+--- a/tests/test_wasyncore.py
++++ b/tests/test_wasyncore.py
+@@ -1451,17 +1451,6 @@ class Test_dispatcher(unittest.TestCase):
+ 
+         return dispatcher(sock=sock, map=map)
+ 
+-    def test_unexpected_getpeername_exc(self):
+-        sock = dummysocket()
+-
+-        def getpeername():
+-            raise OSError(errno.EBADF)
+-
+-        map = {}
+-        sock.getpeername = getpeername
+-        self.assertRaises(socket.error, self._makeOne, sock=sock, map=map)
+-        self.assertEqual(map, {})
+-
+     def test___repr__accepting(self):
+         sock = dummysocket()
+         map = {}
+-- 
+2.30.2
+
diff -Nru waitress-2.1.2/debian/patches/0005-When-closing-the-socket-set-it-to-None.patch waitress-2.1.2/debian/patches/0005-When-closing-the-socket-set-it-to-None.patch
--- waitress-2.1.2/debian/patches/0005-When-closing-the-socket-set-it-to-None.patch	1970-01-01 02:00:00.000000000 +0200
+++ waitress-2.1.2/debian/patches/0005-When-closing-the-socket-set-it-to-None.patch	2025-08-20 18:30:00.000000000 +0300
@@ -0,0 +1,40 @@
+From 4adc02c27a1c8457aacf1d8f058ae8879655bf58 Mon Sep 17 00:00:00 2001
+From: Delta Regeer <bertjw@regeer.org>
+Date: Sun, 3 Mar 2024 16:37:12 -0700
+Subject: When closing the socket, set it to None
+
+This avoids calling close() twice on the same socket if self.close() or
+self.handle_close() is called multiple times
+---
+ src/waitress/wasyncore.py | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/src/waitress/wasyncore.py b/src/waitress/wasyncore.py
+index b3459e0..116c226 100644
+--- a/src/waitress/wasyncore.py
++++ b/src/waitress/wasyncore.py
+@@ -470,6 +470,8 @@ class dispatcher:
+                 if why.args[0] not in (ENOTCONN, EBADF):
+                     raise
+ 
++            self.socket = None
++
+     # log and log_info may be overridden to provide more sophisticated
+     # logging and warning methods. In general, log is for 'hit' logging
+     # and 'log_info' is for informational, warning and error logging.
+@@ -520,7 +522,11 @@ class dispatcher:
+         # handle_expt_event() is called if there might be an error on the
+         # socket, or if there is OOB data
+         # check for the error condition first
+-        err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
++        err = (
++            self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
++            if self.socket is not None
++            else 1
++        )
+         if err != 0:
+             # we can get here when select.select() says that there is an
+             # exceptional condition on the socket
+-- 
+2.30.2
+
diff -Nru waitress-2.1.2/debian/patches/0006-Don-t-exit-handle_write-early-even-if-socket-is-not-.patch waitress-2.1.2/debian/patches/0006-Don-t-exit-handle_write-early-even-if-socket-is-not-.patch
--- waitress-2.1.2/debian/patches/0006-Don-t-exit-handle_write-early-even-if-socket-is-not-.patch	1970-01-01 02:00:00.000000000 +0200
+++ waitress-2.1.2/debian/patches/0006-Don-t-exit-handle_write-early-even-if-socket-is-not-.patch	2025-08-20 18:30:00.000000000 +0300
@@ -0,0 +1,32 @@
+From 3bac1b72c973ed722d29dd58a7bdfba565f1a9b0 Mon Sep 17 00:00:00 2001
+From: Delta Regeer <bertjw@regeer.org>
+Date: Sun, 3 Mar 2024 16:26:22 -0700
+Subject: Don't exit handle_write early -- even if socket is not connected
+
+Calling handle_close() multiple times does not hurt anything, and is
+safe.
+---
+ src/waitress/channel.py | 6 ------
+ 1 file changed, 6 deletions(-)
+
+diff --git a/src/waitress/channel.py b/src/waitress/channel.py
+index 756adce..427c2a7 100644
+--- a/src/waitress/channel.py
++++ b/src/waitress/channel.py
+@@ -92,13 +92,7 @@ class HTTPChannel(wasyncore.dispatcher):
+         # Precondition: there's data in the out buffer to be sent, or
+         # there's a pending will_close request
+ 
+-        if not self.connected:
+-            # we dont want to close the channel twice
+-
+-            return
+-
+         # try to flush any pending output
+-
+         if not self.requests:
+             # 1. There are no running tasks, so we don't need to try to lock
+             #    the outbuf before sending
+-- 
+2.30.2
+
diff -Nru waitress-2.1.2/debian/patches/0007-Assume-socket-is-not-connected-when-passed-to-wasync.patch waitress-2.1.2/debian/patches/0007-Assume-socket-is-not-connected-when-passed-to-wasync.patch
--- waitress-2.1.2/debian/patches/0007-Assume-socket-is-not-connected-when-passed-to-wasync.patch	1970-01-01 02:00:00.000000000 +0200
+++ waitress-2.1.2/debian/patches/0007-Assume-socket-is-not-connected-when-passed-to-wasync.patch	2025-08-20 18:30:00.000000000 +0300
@@ -0,0 +1,51 @@
+From a2cfaab2c980d8e7fd45742dfd3edbcc3b584d5d Mon Sep 17 00:00:00 2001
+From: Delta Regeer <bertjw@regeer.org>
+Date: Sun, 3 Mar 2024 16:16:48 -0700
+Subject: Assume socket is not connected when passed to wasyncore.dispatcher
+
+No longer call getpeername() on the remote socket either, as it is not
+necessary for any of the places where waitress requires that self.addr
+in a subclass of the dispatcher needs it.
+
+This removes a race condition when setting up a HTTPChannel where we
+accepted the socket, and know the remote address, yet call getpeername()
+again which would have the unintended side effect of potentially setting
+self.connected to False because the remote has already shut down part of
+the socket.
+
+This issue was uncovered in #418, where the server would go into a hard
+loop because self.connected was used in various parts of the code base.
+---
+ src/waitress/wasyncore.py | 16 ----------------
+ 1 file changed, 16 deletions(-)
+
+diff --git a/src/waitress/wasyncore.py b/src/waitress/wasyncore.py
+index 116c226..10b0ec9 100644
+--- a/src/waitress/wasyncore.py
++++ b/src/waitress/wasyncore.py
+@@ -298,22 +298,6 @@ class dispatcher:
+             # get a socket from a blocking source.
+             sock.setblocking(0)
+             self.set_socket(sock, map)
+-            self.connected = True
+-            # The constructor no longer requires that the socket
+-            # passed be connected.
+-            try:
+-                self.addr = sock.getpeername()
+-            except OSError as err:
+-                if err.args[0] in (ENOTCONN, EINVAL):
+-                    # To handle the case where we got an unconnected
+-                    # socket.
+-                    self.connected = False
+-                else:
+-                    # The socket is broken in some unknown way, alert
+-                    # the user and remove it from the map (to prevent
+-                    # polling of broken sockets).
+-                    self.del_channel(map)
+-                    raise
+         else:
+             self.socket = None
+ 
+-- 
+2.30.2
+
diff -Nru waitress-2.1.2/debian/patches/0008-HTTPChannel-is-always-created-from-accept-explicitly.patch waitress-2.1.2/debian/patches/0008-HTTPChannel-is-always-created-from-accept-explicitly.patch
--- waitress-2.1.2/debian/patches/0008-HTTPChannel-is-always-created-from-accept-explicitly.patch	1970-01-01 02:00:00.000000000 +0200
+++ waitress-2.1.2/debian/patches/0008-HTTPChannel-is-always-created-from-accept-explicitly.patch	2025-08-20 18:30:00.000000000 +0300
@@ -0,0 +1,27 @@
+From daa92aee796abcf54a46eddd5535fca231c5ce92 Mon Sep 17 00:00:00 2001
+From: Delta Regeer <bertjw@regeer.org>
+Date: Sun, 3 Mar 2024 16:15:51 -0700
+Subject: HTTPChannel is always created from accept, explicitly set
+ self.connected to True
+
+---
+ src/waitress/channel.py | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/src/waitress/channel.py b/src/waitress/channel.py
+index 427c2a7..f4d9677 100644
+--- a/src/waitress/channel.py
++++ b/src/waitress/channel.py
+@@ -67,8 +67,7 @@ class HTTPChannel(wasyncore.dispatcher):
+         self.outbuf_lock = threading.Condition()
+ 
+         wasyncore.dispatcher.__init__(self, sock, map=map)
+-
+-        # Don't let wasyncore.dispatcher throttle self.addr on us.
++        self.connected = True
+         self.addr = addr
+         self.requests = []
+ 
+-- 
+2.30.2
+
diff -Nru waitress-2.1.2/debian/patches/series waitress-2.1.2/debian/patches/series
--- waitress-2.1.2/debian/patches/series	2022-11-14 18:08:02.000000000 +0200
+++ waitress-2.1.2/debian/patches/series	2025-08-20 18:31:13.000000000 +0300
@@ -1,2 +1,10 @@
 docs-Don-t-try-to-detect-the-version-don-t-use-Pylons-the.patch
 docs-Use-internal-ressources-for-intersphinx.patch
+0001-Fix-a-race-condition-on-recv_bytes-boundary-when-req.patch
+0002-Make-DummySock-look-more-like-an-actual-socket.patch
+0003-Add-a-new-test-to-validate-the-lookahead-race-condit.patch
+0004-Remove-test-for-getpeername.patch
+0005-When-closing-the-socket-set-it-to-None.patch
+0006-Don-t-exit-handle_write-early-even-if-socket-is-not-.patch
+0007-Assume-socket-is-not-connected-when-passed-to-wasync.patch
+0008-HTTPChannel-is-always-created-from-accept-explicitly.patch

--- End Message ---
--- Begin Message ---
Package: release.debian.org
Version: 12.12

Hi,

Each of the updates referenced by these requests was included in
today's 12.12 point release for bookworm.

Regards,

Adam

--- End Message ---

Reply to: