[master] 473897cda vre: Don't count on the capture of the 0th group
Dridi Boukelmoune
dridi.boukelmoune at gmail.com
Thu Sep 2 17:12:06 UTC 2021
commit 473897cda00a35188a7bb11cfe2af913c3406e6f
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date: Thu Sep 2 18:59:01 2021 +0200
vre: Don't count on the capture of the 0th group
Using groups[0].e turns out to be unreliable to print the suffix of the
subject string for a regsub operation. On Debian buster, with the help
of ASAN we can observe uninitialized memory through the remains of ASAN's
0xbe pattern that leads later to a complaint about an invalid pointer:
runtime error: pointer index expression with base 0x6310000a0816
overflowed to 0xbebf21cebec8c6d4
With a simple subtraction we can confirm the offset added to the base
address:
0xbebf21cebec8c6d4 - 0x6310000a0816 = 0xbebebebebebebebe
To work around the possibility of an uninitialized ovector depending on
the pcre2 version, we initialize all offsets to PCRE2_UNSET and when we
encounter that value we capture a safe empty token.
This means that at the end of VRE_sub() we can no longer count on the
capture of the 0th group and revert back to using the offset.
diff --git a/lib/libvarnish/vre.c b/lib/libvarnish/vre.c
index 0cf5c9bfd..f5dcc848e 100644
--- a/lib/libvarnish/vre.c
+++ b/lib/libvarnish/vre.c
@@ -188,7 +188,7 @@ vre_capture(const vre_t *code, const char *subject, size_t length,
{
pcre2_match_data *data;
pcre2_code *re;
- PCRE2_SIZE *ovector;
+ PCRE2_SIZE *ovector, b, e;
size_t nov, g;
int matches;
@@ -202,6 +202,11 @@ vre_capture(const vre_t *code, const char *subject, size_t length,
AN(data);
}
+ ovector = pcre2_get_ovector_pointer(data);
+ nov = 2 * pcre2_get_ovector_count(data);
+ for (g = 0; g < nov; g++)
+ ovector[g] = PCRE2_UNSET;
+
matches = pcre2_match(re, (PCRE2_SPTR)subject, length, offset,
options, data, code->re_ctx);
@@ -213,8 +218,14 @@ vre_capture(const vre_t *code, const char *subject, size_t length,
if (nov > *count)
nov = *count;
for (g = 0; g < nov; g++) {
- groups->b = subject + ovector[2 * g];
- groups->e = subject + ovector[2 * g + 1];
+ b = ovector[2 * g];
+ e = ovector[2 * g + 1];
+ if (b == PCRE2_UNSET) {
+ groups->b = groups->e = "";
+ } else {
+ groups->b = subject + b;
+ groups->e = subject + e;
+ }
groups++;
}
*count = nov;
@@ -334,7 +345,7 @@ VRE_sub(const vre_t *code, const char *subject, const char *replacement,
}
/* Copy suffix to match */
- VSB_cat(vsb, groups[0].e);
+ VSB_cat(vsb, subject + offset);
return (1);
}
More information about the varnish-commit
mailing list