You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by cm...@apache.org on 2025/11/10 19:25:31 UTC
(trafficserver) 02/09: Fix of use-after-free tunnel_handler_100_continue_ua (#12561)
This is an automated email from the ASF dual-hosted git repository.
cmcfarlen pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
commit 55dbdeccca2643b337ab1ecb180cbc8172bf9921
Author: Brian Neradt <br...@gmail.com>
AuthorDate: Tue Oct 28 13:46:26 2025 -0500
Fix of use-after-free tunnel_handler_100_continue_ua (#12561)
From a recent instrumented core taking traffic in production:
```
(gdb) p write_state.vio
$22 = {
cont = 0x0,
cont_handler_name = 0x9046f2 "&HttpTunnel::main_handler",
nbytes = 9223372036854775807,
ndone = 0,
op = 2,
_disabled = false,
buffer = {
mbuf = 0x0,
entry = 0x0
},
vc_server = 0x7faa48983920,
mutex = {
m_ptr = 0x7fa7bfa24a00
}
}
```
Notice that:
* cont is nullptr
* nbytes is 9223372036854775807 (INT64_MAX)
These are the default value of do_io_write when no values are passed to
it. This doesn't happen in a lot of places, but it does currently in
tunnel_handler_100_continue_ua:
```cpp
c->vc->do_io_write();
```
This changes the call to the following more typical way of canceling a
vc write operation:
```cpp
c->vc->do_io_write(nullptr, 0, nullptr);
```
This way when a PluginVC::process_timeout event is processed, the ntodo
will be 0 and thus the non-existent handler will not be called (see
PluginVC.cc):
```cpp
} else if (write_state.vio.op == VIO::WRITE && !write_state.shutdown && write_state.vio.ntodo() > 0) {
```
(cherry picked from commit 99d2d3543d095ee4e8cddb83953a28539d74786b)
---
src/proxy/http/HttpSM.cc | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/proxy/http/HttpSM.cc b/src/proxy/http/HttpSM.cc
index 71868c0f61..6c1d152a45 100644
--- a/src/proxy/http/HttpSM.cc
+++ b/src/proxy/http/HttpSM.cc
@@ -3405,9 +3405,9 @@ HttpSM::tunnel_handler_100_continue_ua(int event, HttpTunnelConsumer *c)
_ua.get_entry()->in_tunnel = false;
c->write_success = true;
- // remove the buffer reader from the consumer's vc
+ // Disable any write operation in case there are timeout events.
if (c->vc != nullptr) {
- c->vc->do_io_write();
+ c->vc->do_io_write(nullptr, 0, nullptr);
}
}