Skip to content

Commit 0eac5a1

Browse files
authored
slice: Fix a crash caused by use-after-free (#13113)
1 parent 992584c commit 0eac5a1

3 files changed

Lines changed: 29 additions & 25 deletions

File tree

plugins/slice/Data.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "Stage.h"
2626

2727
#include <netinet/in.h>
28+
#include <string>
2829
#include <unordered_map>
2930

3031
struct Config;
@@ -47,8 +48,8 @@ struct Data {
4748

4849
sockaddr_storage m_client_ip;
4950

50-
// transaction pointer
51-
TSHttpTxn m_txnp{nullptr};
51+
// cached effective URL for use during async intercept processing
52+
std::string m_effective_url;
5253

5354
// for pristine/effective url coming in
5455
TSMBuffer m_urlbuf{nullptr};

plugins/slice/server.cc

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -90,28 +90,24 @@ enum HeaderState {
9090
};
9191

9292
static void
93-
update_object_size(TSHttpTxn txnp, int64_t size, Config &config)
93+
update_object_size(std::string_view const url, int64_t size, Config &config)
9494
{
95-
int urllen = 0;
96-
char *urlstr = TSHttpTxnEffectiveUrlStringGet(txnp, &urllen);
97-
if (urlstr != nullptr) {
98-
if (size <= 0) {
99-
DEBUG_LOG("Ignoring invalid content length for %.*s: %" PRId64, urllen, urlstr, size);
100-
TSfree(urlstr);
101-
return;
102-
}
95+
if (url.empty()) {
96+
ERROR_LOG("Could not get URL from transaction.");
97+
return;
98+
}
10399

104-
if (static_cast<uint64_t>(size) >= config.m_min_size_to_slice) {
105-
config.sizeCacheAdd({urlstr, static_cast<size_t>(urllen)}, static_cast<uint64_t>(size));
106-
TSStatIntIncrement(config.stat_TP, 1);
107-
} else {
108-
config.sizeCacheRemove({urlstr, static_cast<size_t>(urllen)});
109-
TSStatIntIncrement(config.stat_FP, 1);
110-
}
100+
if (size <= 0) {
101+
DEBUG_LOG("Ignoring invalid content length for %.*s: %" PRId64, static_cast<int>(url.size()), url.data(), size);
102+
return;
103+
}
111104

112-
TSfree(urlstr);
105+
if (static_cast<uint64_t>(size) >= config.m_min_size_to_slice) {
106+
config.sizeCacheAdd(url, static_cast<uint64_t>(size));
107+
TSStatIntIncrement(config.stat_TP, 1);
113108
} else {
114-
ERROR_LOG("Could not get URL from transaction.");
109+
config.sizeCacheRemove(url);
110+
TSStatIntIncrement(config.stat_FP, 1);
115111
}
116112
}
117113

@@ -151,7 +147,7 @@ handleFirstServerHeader(Data *const data, TSCont const contp)
151147
}
152148
DEBUG_LOG("Passthru bytes: header: %" PRId64 " body: %" PRId64, hlen, clen);
153149
if (clen != INT64_MAX) {
154-
update_object_size(data->m_txnp, clen, *data->m_config);
150+
update_object_size(data->m_effective_url, clen, *data->m_config);
155151
TSVIONBytesSet(output_vio, hlen + clen);
156152
} else {
157153
TSVIONBytesSet(output_vio, clen);
@@ -171,7 +167,7 @@ handleFirstServerHeader(Data *const data, TSCont const contp)
171167
return HeaderState::Fail;
172168
}
173169

174-
update_object_size(data->m_txnp, blockcr.m_length, *data->m_config);
170+
update_object_size(data->m_effective_url, blockcr.m_length, *data->m_config);
175171

176172
// set the resource content length from block response
177173
data->m_contentlen = blockcr.m_length;

plugins/slice/slice.cc

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,14 @@ read_request(TSHttpTxn txnp, Config *const config, TSCont read_resp_hdr_contp)
108108
std::unique_ptr<Data> data = std::make_unique<Data>(config);
109109

110110
data->m_method_type = header.method();
111-
data->m_txnp = txnp;
111+
112+
// Cache the effective URL now while txnp is still valid
113+
int efflen = 0;
114+
char *effstr = TSHttpTxnEffectiveUrlStringGet(txnp, &efflen);
115+
if (effstr != nullptr) {
116+
data->m_effective_url.assign(effstr, efflen);
117+
TSfree(effstr);
118+
}
112119

113120
// set up feedback connect
114121
if (AF_INET == ip->sa_family) {
@@ -200,8 +207,8 @@ read_request(TSHttpTxn txnp, Config *const config, TSCont read_resp_hdr_contp)
200207
}
201208
}
202209

203-
data->m_buffer_index = TSPluginVCIOBufferIndexGet(data->m_txnp); // default of m_buffer_index = 32KB
204-
data->m_buffer_water_mark = TSPluginVCIOBufferWaterMarkGet(data->m_txnp); // default of m_buffer_water_mark = 0
210+
data->m_buffer_index = TSPluginVCIOBufferIndexGet(txnp); // default of m_buffer_index = 32KB
211+
data->m_buffer_water_mark = TSPluginVCIOBufferWaterMarkGet(txnp); // default of m_buffer_water_mark = 0
205212

206213
if (dbg_ctl.on()) {
207214
int len = 0;

0 commit comments

Comments
 (0)