pcre2_compile: zero-initialize code area before second-pass compilation - #929
Closed
KwisatzHaderach wants to merge 1 commit into
Closed
pcre2_compile: zero-initialize code area before second-pass compilation#929KwisatzHaderach wants to merge 1 commit into
KwisatzHaderach wants to merge 1 commit into
Conversation
When PCRE2 is used as a non-MSan-instrumented shared library inside an
MSan-instrumented program, bytes written to the compiled code via direct
assignment (e.g. literal character data for OP_CHAR opcodes) are not tracked
in MSan's shadow memory. The JIT compiler's detect_repeat() calls memcmp()
over compiled bytecode blocks, and MSan's memcmp interceptor reports a
use-of-uninitialized-value error for those character bytes.
Fix by zeroing the code area with memset() before the second compilation pass.
MSan's memset interceptor marks all code bytes as initialized in the shadow;
the compiler then overwrites them with the actual bytecode values. This
eliminates the spurious MSan error without any correctness impact.
Reproducer (requires clang + system PCRE2 without MSan instrumentation):
clang -fsanitize=memory -o test test.c -lpcre2-8
// test.c:
#define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h>
int main(void) {
int e; PCRE2_SIZE off;
pcre2_code *re = pcre2_compile(
(PCRE2_SPTR)"^(/foo/bar)(/foo/bar)$",
PCRE2_ZERO_TERMINATED, PCRE2_DOTALL, &e, &off, NULL);
pcre2_jit_compile(re, PCRE2_JIT_COMPLETE | PCRE2_JIT_PARTIAL_SOFT);
}
// => MSan: use-of-uninitialized-value in memcmp inside pcre2_jit_compile_8
Tested on: aarch64 (PCRE2 10.44) and x86_64 (PCRE2 10.47).
Signed-off-by: Petr Matyas <p.matyas13@gmail.com>
Contributor
|
The documentation from memory sanitizer, mentions
This doesn't reproduce if the PCRE2 library is instrumented as well, hence it is one of those false reports. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When PCRE2 is used as a non-MSan-instrumented shared library inside an MSan-instrumented program, bytes written to the compiled code via direct assignment (e.g. literal character data for OP_CHAR opcodes) are not tracked in MSan's shadow memory. The JIT compiler's detect_repeat() calls memcmp() over compiled bytecode blocks, and MSan's memcmp interceptor reports a use-of-uninitialized-value error for those character bytes.
Fix by zeroing the code area with memset() before the second compilation pass. MSan's memset interceptor marks all code bytes as initialized in the shadow; the compiler then overwrites them with the actual bytecode values. This eliminates the spurious MSan error without any correctness impact.
Reproducer (requires clang + system PCRE2 without MSan instrumentation):
clang -fsanitize=memory -o test test.c -lpcre2-8
// test.c:
#define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h>
int main(void) {
int e; PCRE2_SIZE off;
pcre2_code *re = pcre2_compile(
(PCRE2_SPTR)"^(/foo/bar)(/foo/bar)$",
PCRE2_ZERO_TERMINATED, PCRE2_DOTALL, &e, &off, NULL);
pcre2_jit_compile(re, PCRE2_JIT_COMPLETE | PCRE2_JIT_PARTIAL_SOFT);
}
// => MSan: use-of-uninitialized-value in memcmp inside pcre2_jit_compile_8
Tested on: aarch64 (PCRE2 10.44) and x86_64 (PCRE2 10.47).