From: Kevin Willford <kewillf@xxxxxxxxxxxxx> Add check for the end of the entries for the thread partition. Add test for lazy init name hash with specific directory structure The lazy init hash name was causing a buffer overflow when the last entry in the index was multiple folder deep with parent folders that did not have any files in them. This adds a test for the boundary condition of the thread partitions with the folder structure that was triggering the buffer overflow. The test is skipped on single-cpu machines because the original code path is used in name-hash.c The fix was to check if it is the last entry for the thread partition in the handle_range_dir and not try to use the next entry in the cache. Signed-off-by: Kevin Willford <kewillf@xxxxxxxxxxxxx> Signed-off-by: Johannes Schindelin <johannes.schindelin@xxxxxx> Signed-off-by: Jeff Hostetler <jeffhost@xxxxxxxxxxxxx> --- name-hash.c | 4 +++- t/t3008-ls-files-lazy-init-name-hash.sh | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100755 t/t3008-ls-files-lazy-init-name-hash.sh diff --git a/name-hash.c b/name-hash.c index cac313c..39309ef 100644 --- a/name-hash.c +++ b/name-hash.c @@ -342,7 +342,9 @@ static int handle_range_dir( * Scan forward in the index array for index entries having the same * path prefix (that are also in this directory). */ - if (strncmp(istate->cache[k_start + 1]->name, prefix->buf, prefix->len) > 0) + if (k_start + 1 >= k_end) + k = k_end; + else if (strncmp(istate->cache[k_start + 1]->name, prefix->buf, prefix->len) > 0) k = k_start + 1; else if (strncmp(istate->cache[k_end - 1]->name, prefix->buf, prefix->len) == 0) k = k_end; diff --git a/t/t3008-ls-files-lazy-init-name-hash.sh b/t/t3008-ls-files-lazy-init-name-hash.sh new file mode 100755 index 0000000..bdf5198 --- /dev/null +++ b/t/t3008-ls-files-lazy-init-name-hash.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +test_description='Test the lazy init name hash with various folder structures' + +. ./test-lib.sh + +if test 1 -eq $($GIT_BUILD_DIR/t/helper/test-online-cpus) +then + skip_all='skipping lazy-init tests, single cpu' + test_done +fi + +LAZY_THREAD_COST=2000 + +test_expect_success 'no buffer overflow in lazy_init_name_hash' ' + ( + test_seq $LAZY_THREAD_COST | sed "s/^/a_/" + echo b/b/b + test_seq $LAZY_THREAD_COST | sed "s/^/c_/" + test_seq 50 | sed "s/^/d_/" | tr "\n" "/"; echo d + ) | + sed "s/^/100644 $EMPTY_BLOB /" | + git update-index --index-info && + test-lazy-init-name-hash -m +' + +test_done -- 2.9.3