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 a50f7e3c063dcd19c3cf4187334ab19676a99bf1 Author: Masakazu Kitajo <[email protected]> AuthorDate: Wed Apr 22 11:14:30 2026 -0600 slice: Fix a crash caused by use-after-free (#13113) (cherry picked from commit 0eac5a15f2e9c073c0da34387ce05914a93283c3) --- plugins/slice/Data.h | 5 +++-- plugins/slice/server.cc | 35 ++++++++++++++++------------------- plugins/slice/slice.cc | 13 ++++++++++--- 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/plugins/slice/Data.h b/plugins/slice/Data.h index 754a2c331e..0628dc936d 100644 --- a/plugins/slice/Data.h +++ b/plugins/slice/Data.h @@ -25,6 +25,7 @@ #include "Stage.h" #include <netinet/in.h> +#include <string> #include <unordered_map> struct Config; @@ -49,8 +50,8 @@ struct Data { sockaddr_storage m_client_ip; - // transaction pointer - TSHttpTxn m_txnp{nullptr}; + // cached effective URL for use during async intercept processing + std::string m_effective_url; // for pristine/effective url coming in TSMBuffer m_urlbuf{nullptr}; diff --git a/plugins/slice/server.cc b/plugins/slice/server.cc index bad9947994..3158c786ad 100644 --- a/plugins/slice/server.cc +++ b/plugins/slice/server.cc @@ -89,27 +89,24 @@ enum HeaderState { }; static void -update_object_size(TSHttpTxn txnp, int64_t size, Config &config) +update_object_size(std::string_view const url, int64_t size, Config &config) { - int urllen = 0; - char *urlstr = TSHttpTxnEffectiveUrlStringGet(txnp, &urllen); - if (urlstr != nullptr) { - if (size <= 0) { - DEBUG_LOG("Ignoring invalid content length for %.*s: %" PRId64, urllen, urlstr, size); - return; - } + if (url.empty()) { + ERROR_LOG("Could not get URL from transaction."); + return; + } - if (static_cast<uint64_t>(size) >= config.m_min_size_to_slice) { - config.sizeCacheAdd({urlstr, static_cast<size_t>(urllen)}, static_cast<uint64_t>(size)); - TSStatIntIncrement(config.stat_TP, 1); - } else { - config.sizeCacheRemove({urlstr, static_cast<size_t>(urllen)}); - TSStatIntIncrement(config.stat_FP, 1); - } + if (size <= 0) { + DEBUG_LOG("Ignoring invalid content length for %.*s: %" PRId64, static_cast<int>(url.size()), url.data(), size); + return; + } - TSfree(urlstr); + if (static_cast<uint64_t>(size) >= config.m_min_size_to_slice) { + config.sizeCacheAdd(url, static_cast<uint64_t>(size)); + TSStatIntIncrement(config.stat_TP, 1); } else { - ERROR_LOG("Could not get URL from transaction."); + config.sizeCacheRemove(url); + TSStatIntIncrement(config.stat_FP, 1); } } @@ -147,7 +144,7 @@ handleFirstServerHeader(Data *const data, TSCont const contp) } DEBUG_LOG("Passthru bytes: header: %" PRId64 " body: %" PRId64, hlen, clen); if (clen != INT64_MAX) { - update_object_size(data->m_txnp, clen, *data->m_config); + update_object_size(data->m_effective_url, clen, *data->m_config); TSVIONBytesSet(output_vio, hlen + clen); } else { TSVIONBytesSet(output_vio, clen); @@ -167,7 +164,7 @@ handleFirstServerHeader(Data *const data, TSCont const contp) return HeaderState::Fail; } - update_object_size(data->m_txnp, blockcr.m_length, *data->m_config); + update_object_size(data->m_effective_url, blockcr.m_length, *data->m_config); // set the resource content length from block response data->m_contentlen = blockcr.m_length; diff --git a/plugins/slice/slice.cc b/plugins/slice/slice.cc index 9be1a8b729..119f28c539 100644 --- a/plugins/slice/slice.cc +++ b/plugins/slice/slice.cc @@ -105,7 +105,14 @@ read_request(TSHttpTxn txnp, Config *const config, TSCont read_resp_hdr_contp) std::unique_ptr<Data> data = std::make_unique<Data>(config); data->m_method_type = header.method(); - data->m_txnp = txnp; + + // Cache the effective URL now while txnp is still valid + int efflen = 0; + char *effstr = TSHttpTxnEffectiveUrlStringGet(txnp, &efflen); + if (effstr != nullptr) { + data->m_effective_url.assign(effstr, efflen); + TSfree(effstr); + } // set up feedback connect if (AF_INET == ip->sa_family) { @@ -197,8 +204,8 @@ read_request(TSHttpTxn txnp, Config *const config, TSCont read_resp_hdr_contp) } } - data->m_buffer_index = TSPluginVCIOBufferIndexGet(data->m_txnp); // default of m_buffer_index = 32KB - data->m_buffer_water_mark = TSPluginVCIOBufferWaterMarkGet(data->m_txnp); // default of m_buffer_water_mark = 0 + data->m_buffer_index = TSPluginVCIOBufferIndexGet(txnp); // default of m_buffer_index = 32KB + data->m_buffer_water_mark = TSPluginVCIOBufferWaterMarkGet(txnp); // default of m_buffer_water_mark = 0 if (dbg_ctl.on()) { int len = 0;
