[PATCH v3 0/3] Fix a segfault caused by regexec() being called on mmap()ed data
- From
Johannes Schindelin <johannes.schindelin@gmx.de>
- Date
- Sep 8, 2016, 07:57 UTC
- Message-ID
- <cover.1473321437.git.johannes.schindelin@gmx.de>
- In-Reply-To
- <cover.1473319844.git.johannes.schindelin@gmx.de>
This patch series addresses a problem where `git diff` is called using `-G` or `-S --pickaxe-regex` on new-born files that are configured without user diff drivers, and that hence get mmap()ed into memory.
The problem with that: mmap()ed memory is *not* NUL-terminated, yet the pickaxe code calls regexec() on it just the same.
This problem has been reported by my colleague Chris Sidi.
We solve this by introducing a helper, regexec_buf(), that takes a pointer and a length instead of a NUL-terminated string.
This helper then uses REG_STARTEND where available, and falls back to allocating and constructing a NUL-terminated string. Given the wide-spread support for REG_STARTEND (Linux has it, MacOSX has it, Git for Windows has it because it uses compat/regex/ that has it), I think this is a fair trade-off.
Changes since v2:
- changed 3/3 to switch the test_expect_failure from 1/3 to a test_expect_success
Johannes Schindelin (3): Demonstrate a problem: our pickaxe code assumes NUL-terminated buffers Introduce a function to run regexec() on non-NUL-terminated buffers Use the newly-introduced regexec_buf() function
diff.c | 3 ++- diffcore-pickaxe.c | 18 ++++++++---------- git-compat-util.h | 21 +++++++++++++++++++++ t/t4061-diff-pickaxe.sh | 22 ++++++++++++++++++++++ xdiff-interface.c | 13 ++++--------- 5 files changed, 57 insertions(+), 20 deletions(-) create mode 100755 t/t4061-diff-pickaxe.sh
Published-As: https://github.com/dscho/git/releases/tag/mmap-regexec-v3 Fetch-It-Via: git fetch https://github.com/dscho/git mmap-regexec-v3
Interdiff vs v2:
diff --git a/t/t4061-diff-pickaxe.sh b/t/t4061-diff-pickaxe.sh
index 5929f2e..f0bf50b 100755
--- a/t/t4061-diff-pickaxe.sh
+++ b/t/t4061-diff-pickaxe.sh
@@ -14,7 +14,7 @@ test_expect_success setup '
test_tick &&
git commit -m "A 4k file"
'
-test_expect_failure '-G matches' '
+test_expect_success '-G matches' '
git diff --name-only -G "^0{4096}$" HEAD^ >out &&
test 4096-zeroes.txt = "$(cat out)"
'-- 2.10.0.windows.1.10.g803177d base-commit: 6ebdac1bab966b720d776aa43ca188fe378b1f4b