Re: [PATCH] scalar: avoid segfault in reconfigure --all
- From
Patrick Steinhardt <ps@pks.im>
- Date
- May 2, 2024, 06:46 UTC
- Message-ID
- <ZjM23X_Tf3pcWsIq@tanuki>
- In-Reply-To
- <pull.1724.git.1714496333004.gitgitgadget@gmail.com>
On Tue, Apr 30, 2024 at 04:58:52PM +0000, Derrick Stolee via GitGitGadget wrote:
Show 16 quoted lines
> From: Derrick Stolee <stolee@gmail.com> > > During the latest v2.45.0 update, 'scalar reconfigure --all' started to > segfault on my machine. Breaking it down via the debugger, it was > faulting on a NULL reference to the_hash_algo, which is a macro pointing > to the_repository->hash_algo. > > This NULL reference appears to be due to the way the loop is abusing the > the_repository pointer, pointing it to a local repository struct after > discovering that the current directory is a valid Git repository. This > repo-swapping bit was in the original implementation from 4582676075 > (scalar: teach 'reconfigure' to optionally handle all registered > enlistments, 2021-12-03), but only recently started segfaulting while > trying to parse the HEAD reference. This also only happens on the > _second_ repository in the list, so does not reproduce if there is only > one registered repo.
Interesting. This also has some overlap with my patch series that aims to drop the default-SHA1 fallback that we have in place for `the_repository` [1].
Show 5 quoted lines
> Add a test to t9210-scalar.sh to test 'scalar reconfigure --all' with > multiple registered repos, as a precaution. Unfortunately, I was unable > to reproduce the segfault using this test, so there is some coverage > left to be desired. What exactly causes my setup to hit this bug but not > this test structure? Unclear.
One way to trigger _a_ BUG is to use an "includeIf.onbranch:foobar.path" config. This will cause Git to try and look up the "HEAD" reference, but because we have a partially-configured repository, only, that will crash with:
BUG: refs.c:2123: reference backend is unknown
Whether that bug is the one that you have seen I cannot tell. It at least does not sound like it.
test_expect_success 'scalar reconfigure --all with includeIf.onbranch' '
repos="two three four" &&
for num in $repos
do
git init $num/src &&
scalar register $num/src &&
git -C $num/src config includeif."onbranch:foo".path something &&
git -C $num/src config core.preloadIndex false || return 1
done &&scalar reconfigure --all &&
for num in $repos
do
test true = "$(git -C $num/src config core.preloadIndex)" || return 1
done
'Another issue, which is likely the one you report here, is if you have a repository with detached "HEAD". In that case we use `get_oid_hex()` to parse "HEAD", which will implicitly use `the_hash_algo`. But because you unset it in the second round this will fail with a segfault when you try to access it:
./test-lib.sh: line 1069: 583995 Segmentation fault (core dumped) scalar reconfigure --all
This is the following testcase:
test_expect_success 'scalar reconfigure --all with detached HEADs' '
repos="two three four" &&
for num in $repos
do
rm -rf $num/src &&
git init $num/src &&
scalar register $num/src &&
git -C $num/src config core.preloadIndex false &&
test_commit -C $num/src initial &&
git -C $num/src switch --detach HEAD || return 1
done &&scalar reconfigure --all &&
for num in $repos
do
test true = "$(git -C $num/src config core.preloadIndex)" || return 1
done
'This issue should be fixed by my patch series in [1] because we start to use `get_oid_hex_any()` to parse detached HEADs.
Anyway, your fix is indeed effective because with `repo_init()` we now properly configure the repository.
[1]: https://lore.kernel.org/git/cover.1714371422.git.ps@pks.im/
Patrick