[PATCH v2 0/1] maintenance: Fix SEGFAULT when running outside of a repository
- From
Rafael Silva <rafaeloliveira.cs@gmail.com>
- Date
- Nov 26, 2020, 20:41 UTC
- Message-ID
- <20201126204141.1438-1-rafaeloliveira.cs@gmail.com>
- In-Reply-To
- <20201124164405.29327-1-rafaeloliveira.cs@gmail.com>
In d7514f6ed5 (maintenance: take a lock on the objects directory, 2020-09-17) [1], and 2fec604f8d (maintenance: add start/stop subcommands, 2020-09-11) [2] The "git maintenance run" and "git maintenance start" was taught to hold a file-based lock at the .git/maintenance.lock and .git/schedule.lock respectively because these operations involves writing data into the .git/repository.
The lock file path string is built using the the_repository->objects->odb->path, in case the_repository->objects->odb is NULL when there is not repository available, resulting in a SEGFAULT.
In order to reproduce the error, one can execute maintenance "run" and/or "start" subcommand with a non valid repository:
$ git -C /tmp maintenance start
Segmentation fault $ git -C /tmp maintenance run
Segmentation faultThe above test was executed from a git built from commit: faefdd61ec (Sixth batch, 2020-11-18):
For reference here's the output from GDB when debugging the "start" command
Program received signal SIGSEGV, Segmentation fault.
0x00005555555b9b4c in maintenance_run_tasks (opts=0x7fffffffded4) at builtin/gc.c:1268
1268 char *lock_path = xstrfmt("%s/maintenance", r->objects->odb->path);Updates in v2 =============
* Instead of implementing the check on the subcommands, a more robust approach
is taken by replacing the "maintenance" command option to use RUN_SETUP
instead of RUN_SETUP_GENTLY as suggested by Derrick Stolee in [3] as part of
review cycle from v1. This provides protection for all maintenance subcommands given that
currently all the commands are required to be executed inside a repository. * As the RUN_SETUP will enable protection to all commands, the checks in
maintenance_register() and maintenance_unregister() are removed as they
are not required anymore. * Use the "nongit" helper function for testing it instead of relying on the
`/tmp` directory for a non valid git repository as suggested by
SZEDER Gábor and Eric Sunshine in [4].* All "git maintenance" subcommands are included on the test to ensure the behaviour is consistent for all subcommands. In particular the "register" command that current exists without a message and code 0 which will be changed by this patch to fail when running outside of a repository.
It also worth noting that "register" command does not exists in a released version of Git as mentioned in [5] which make it easier for changing the current behaviour of the command
[1] https://lore.kernel.org/git/1a0a3eebb825ac3eabfdd86f82ed7ef6abb454c5.1600366313.git.gitgitgadget@gmail.com/ [2] https://lore.kernel.org/git/5194f6b1facbd14cc17eea0337c0cc397a2a51fc.1602782524.git.gitgitgadget@gmail.com/ [3] https://lore.kernel.org/git/1bfd84da-5b74-be10-fc2c-dee80111ee2d@gmail.com/ [4] https://lore.kernel.org/git/20201124191407.GC8396@szeder.dev/ [5] https://lore.kernel.org/git/54fa678c-7150-8c48-50e5-b33923a69249@gmail.com/
Thanks everyone for the insightful and helpful feedback.
Rafael Silva (1): maintenance: fix SEGFAULT when no repository
builtin/gc.c | 7 ------- git.c | 2 +- t/t7900-maintenance.sh | 8 ++++++++ 3 files changed, 9 insertions(+), 8 deletions(-)
-- 2.29.2.367.g37477fb670