Repository navigation
Conversation
When Git's native Windows environment omits its usr/bin directory from
PATH, locate_in_PATH("sh") returns NULL. git_shell_path() passes that value
to convert_slashes(), causing git-remote-https.exe to terminate with an
access violation while preparing a credential helper.
Report the missing shell as a fatal Git error instead. This avoids the
NULL-pointer dereference and adds a Windows-only regression test that
clears PATH inside test-tool and verifies the diagnostic.
Signed-off-by: Peter Kowalczyk <peter@slix.io>
Running Git for Windows in an environment where Therefore, this PR looks like a fix for something that is not considered a bug, but an incorrect usage of |
While that is true, I still think clearly telling the user that they messed up their setup is nicer than crashing with a |
dscho
left a comment
There was a problem hiding this comment.
While this is definitely outside of the supported use cases of Git for Windows, I am sympathetic to the desire. Maybe these two concerns could be addressed?
|
|
||
| unsetenv("PATH"); | ||
| path = git_shell_path(); | ||
| free(path); |
There was a problem hiding this comment.
Hmm. Is it not possible to do the very same thing in a lot less lines, in a subshell? (unset PATH && git var GIT_SHELL_PATH) should do the same job, without changes to the t/helper/ code, no?
| if (!p) | ||
| die(_("cannot find 'sh' in PATH")); |
There was a problem hiding this comment.
This function is called in two places:
This latter code path, prepare_shell_cmd(), worries me. It's right smack down in the libified part of Git, i.e. it's supposed to return error() and never simply exit() (which die() does). It's called from:
- [
prepare_cmd()]https://github.com/git-for-windows/git/blob/v2.56.0-rc2.windows.1/run-command.c#L424), which is called fromstart_command(), and from - directly from
start_command()
Of course, one could argue that this start_command() function is definitely not thoroughly libified, calling child_die() in a couple of circumstances. But I don't think it'd be a good idea to add on top of the challenges to properly make this a library function that callers can rely on cleaning up resources and returning proper errors instead of simply taking down the entire process. That would make the ongoing libification effort even harder than it already is.
There was a problem hiding this comment.
A better alternative to die() might be to hard-code the absolute path to sh.exe in git_exec_path() (via a static char * that is initialized to xstrfmt( "%s/sh.exe", git_exec_path()) if needed and still NULL). That way, the process will be started, and it will fail with exit code 127 which is at least catchable by the callers.
|
#6475 seems to be helped by this, so I am a lot more willing to merge this (after addressing the libification concern). |
Summary
On native Windows,
git_shell_path()assumes thatlocate_in_PATH("sh")always succeeds and passes its result directly to
convert_slashes(). Ifshis absent fromPATH, the lookup returnsNULLand Git terminateswith an access violation.
Check the lookup result and report a fatal error instead:
This prevents the NULL dereference. It does not add a shell fallback, so
commands requiring a shell still fail when no shell is available.
Crash analysis
The failure was reproduced in
git-remote-https.exefrom Git for Windows2.55.0.windows.3. ProcDump captured the unhandled exception:
The dump confirms that the faulting instruction attempted to read through
RAXwhileRAXwas zero:Correlation of the surrounding disassembly with the source shows it
loading
"sh", performing the PATH lookup, and then entering the slashconversion. This matches the native Windows implementation:
The reproduced missing-
shcondition therefore leavespasNULL,which is dereferenced by
convert_slashes().Regression test
Add a MINGW-only regression test that clears
PATHinsidetest-tool run-command, callsgit_shell_path(), and verifies that Gitreports the controlled fatal diagnostic instead of crashing.
The helper clears
PATHafter process startup, making the missing-shellcondition deterministic without depending on Windows startup PATH
reconstruction.
Testing
Passed:
git diff --checkt/t0061-run-command.shThe native Windows test suite was not run locally because a Git for

Windows SDK/compiler was unavailable in the test environment. Windows CI
is expected to build the change and run
t0061-run-command.sh.