This is an automated email from the ASF dual-hosted git repository.
moonchen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new 92112e1b8a header_rewrite: Fix a leak and truncation in set-body-from
(#13303)
92112e1b8a is described below
commit 92112e1b8ac31030c150f321e98392e7766b503f
Author: Mo Chen <[email protected]>
AuthorDate: Sat Jun 20 08:54:42 2026 -0500
header_rewrite: Fix a leak and truncation in set-body-from (#13303)
Two related fixes in the header_rewrite set-body-from operator's
createRequestString():
Memory leak. The request URL was fetched with TSUrlStringGet(), which
returns a TSmalloc()-allocated buffer the caller owns, but it was never freed.
Every non-internal transaction matching a set-body-from rule leaked one
URL-sized allocation, growing unbounded over time. Free it, mirroring the
existing owned-pointer handling in ConditionUrl.
Truncation / buffer over-read. snprintf() returns the length it would have
written, not the number of bytes actually written, and that value can exceed
the 256-byte req_buf. Passing it to TSFetchUrl() as the request length reads
past the stack buffer when a URL overflows. The request has always been capped
at 256 bytes — snprintf() only ever writes that much into req_buf — so this
changes nothing for requests that fit; it just returns TS_ERROR on overflow
instead of over-reading. (Rai [...]
---
plugins/header_rewrite/operators.cc | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/plugins/header_rewrite/operators.cc
b/plugins/header_rewrite/operators.cc
index 20207bd24b..2913c9349f 100644
--- a/plugins/header_rewrite/operators.cc
+++ b/plugins/header_rewrite/operators.cc
@@ -100,12 +100,19 @@ createRequestString(const std::string_view &value, char
(&req_buf)[MAX_SIZE], in
if (TSUrlCreate(url_buf, &url_loc) == TS_SUCCESS && TSUrlParse(url_buf,
url_loc, &start, end) == TS_PARSE_DONE) {
const char *host = TSUrlHostGet(url_buf, url_loc, &host_len);
- const char *url = TSUrlStringGet(url_buf, url_loc, &url_len);
+ char *url = TSUrlStringGet(url_buf, url_loc, &url_len);
- *req_buf_size = snprintf(req_buf, MAX_SIZE, "GET %.*s HTTP/1.1\r\nHost:
%.*s\r\n\r\n", url_len, url, host_len, host);
+ int written = snprintf(req_buf, MAX_SIZE, "GET %.*s HTTP/1.1\r\nHost:
%.*s\r\n\r\n", url_len, url, host_len, host);
+ TSfree(url);
TSMBufferDestroy(url_buf);
+ if (written < 0 || static_cast<unsigned int>(written) >= MAX_SIZE) {
+ Dbg(pi_dbg_ctl, "Request string does not fit in %u byte buffer, not
sending truncated request", MAX_SIZE);
+ return TS_ERROR;
+ }
+ *req_buf_size = written;
+
return TS_SUCCESS;
} else {
Dbg(pi_dbg_ctl, "Failed to parse url %s", start);