Skip to content

Git Bash: support running on ARM64 without ARM64 binaries again#46

Merged
dscho merged 9 commits intogit-for-windows:mainfrom
dscho:safer-arm64-support-for-git
Feb 13, 2021
Merged

Git Bash: support running on ARM64 without ARM64 binaries again#46
dscho merged 9 commits intogit-for-windows:mainfrom
dscho:safer-arm64-support-for-git

Conversation

@dscho
Copy link
Member

@dscho dscho commented Feb 12, 2021

I have no way to test this. @dennisameling, could you?

By mistake, a camelCased function name was introduced.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
dscho added a commit to dscho/git that referenced this pull request Feb 12, 2021
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
dscho added a commit to dscho/git that referenced this pull request Feb 12, 2021
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
dscho added a commit to dscho/git that referenced this pull request Feb 12, 2021
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
@dscho dscho force-pushed the safer-arm64-support-for-git branch from c2c0990 to 36a87e9 Compare February 12, 2021 13:08
dscho added a commit to dscho/git that referenced this pull request Feb 12, 2021
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
WCHAR msystem_bin2[64];

/* Maybe we are on ARM64 but don't have the binaries? */
swprintf(msystem_bin2, sizeof(msystem_bin2), L"mingw%d\\bin", (int) sizeof(void *) * 8);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this check for the arm64\bin folder instead? If that doesn't exist, we're running on ARM64 but don't have the binaries, correct?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and we're already in the clause where we determined that arm64/bin does not exist. So we're falling back, looking for mingw<bitness>/bin here.

@dennisameling
Copy link

Sure, will test later today!

@dscho
Copy link
Member Author

dscho commented Feb 12, 2021

Sure, will test later today!

Thank you!

@dscho
Copy link
Member Author

dscho commented Feb 12, 2021

Sure, will test later today!

Thank you!

BTW I should have said this earlier: I am trying a slightly patched git-artifacts.yml to produce the corresponding installer/portable artifacts: https://github.com/dscho/git/runs/1887544878?check_suite_focus=true. Maybe that makes it quicker for you to test?

@dennisameling
Copy link

Holy moly - just tested 32-bit Git and can confirm the fork bomb. Not good!

image

Just about to test this PR now

@dennisameling
Copy link

dennisameling commented Feb 12, 2021

Tried with the generated binaries from your CI run (https://github.com/dscho/git/actions/runs/561141041), but the fork bomb is still there unfortunately. Tried building locally based on this PR just to be sure, but then ran into https://github.com/git-for-windows/git-sdk-32/issues/7😞 tried fixing it for an hour by installing/removing all kinds of pacman packages, to no avail

@dscho
Copy link
Member Author

dscho commented Feb 12, 2021

can confirm the fork bomb.

BTW which git.exe is this, is it cmd/git.exe that fork-bombs, or is it mingw32/bin/git.exe? From the size 3.3MB I suspect that it might actually be mingw32/bin/git.exe?

@dennisameling
Copy link

dennisameling commented Feb 12, 2021

It's C:\Program Files (x86)\Git\bin\git.exe if I open the file location:

image

image

@dennisameling
Copy link

Getting a warning while compiling git-wrapper though:

$ make -C src/git -f ../mingw-w64-git.mak git-wrapper.exe
make: Entering directory '/usr/src/MINGW-packages/mingw-w64-git/src/git'
    * new prefix flags
    CC git-wrapper.o
../git-wrapper.c: In function 'is_running_on_arm64':
../git-wrapper.c:129:3: warning: initialization of 'BOOL (*)(void *, USHORT *, USHORT *)' {aka 'int (*)(void *, short unsigned int *, short unsigned int *)'} from incompatible pointer type 'FARPROC' {aka 'long long int (*)()'} [-Wincompatible-pointer-types]
  129 |   GetProcAddress(GetModuleHandle(L"kernel32"), "IsWow64Process2");
      |   ^~~~~~~~~~~~~~
    RC git.res
    LINK git-wrapper.exe
make: Leaving directory '/usr/src/MINGW-packages/mingw-w64-git/src/git'

@dscho
Copy link
Member Author

dscho commented Feb 12, 2021

Okay, so it probably does not detect the correct top-level directory. Maybe patch the git-wrapper.c for testing

Getting a warning while compiling git-wrapper though:

$ make -C src/git -f ../mingw-w64-git.mak git-wrapper.exe
make: Entering directory '/usr/src/MINGW-packages/mingw-w64-git/src/git'
    * new prefix flags
    CC git-wrapper.o
../git-wrapper.c: In function 'is_running_on_arm64':
../git-wrapper.c:129:3: warning: initialization of 'BOOL (*)(void *, USHORT *, USHORT *)' {aka 'int (*)(void *, short unsigned int *, short unsigned int *)'} from incompatible pointer type 'FARPROC' {aka 'long long int (*)()'} [-Wincompatible-pointer-types]
  129 |   GetProcAddress(GetModuleHandle(L"kernel32"), "IsWow64Process2");
      |   ^~~~~~~~~~~~~~
    RC git.res
    LINK git-wrapper.exe
make: Leaving directory '/usr/src/MINGW-packages/mingw-w64-git/src/git'

Yeah, I stumbled over this, too, but it is harmless. I thought that casting to (void (*)(void)) should fix it, but it didn't. Anyway, that's not my main worry now.

The main worry is what is going wrong, and I could imagine that it makes most sense to patch git-wrapper.exe to not actually call CreateProcessW() but instead to print the path to stderr and then exit.

And then you could even compile it using gcc -g -o git-wrapper.exe git-wrapper.c, copy it into a portable Git, and use gdb -args /path/to/bin/git.exe version to debug it.

@dennisameling
Copy link

dennisameling commented Feb 12, 2021

Can't we simply do a _waccess check for arm64/bin in the is_running_on_arm64() function? If it isn't found then it'll simply return false/0 and the system will behave as MINGW32 etc. - I'm currently trying to test that theory but as a beginner in C, it's not as easy as it sounds 😅

@dscho
Copy link
Member Author

dscho commented Feb 12, 2021

Can't we simply do a _waccess check for arm64/bin in the is_running_on_arm64() function?

We don't know the absolute path, then. Remember, we could call this via absolute path, or via PATH from anywhere.

@dscho
Copy link
Member Author

dscho commented Feb 12, 2021

That's why I implemented it at that point: 2ecdd7e

@dscho
Copy link
Member Author

dscho commented Feb 12, 2021

BTW we'll want to add this in an extra commit, I think:

diff --git a/mingw-w64-git/git-wrapper.c b/mingw-w64-git/git-wrapper.c
index 130fc1adc..68bc73bd2 100644
--- a/mingw-w64-git/git-wrapper.c
+++ b/mingw-w64-git/git-wrapper.c
@@ -712,7 +712,7 @@ int main(void)
 		is_git_command = 1, full_path = 1, skip_arguments = 0,
 		allocate_console = 0, show_console = -1,
 		append_quote_to_cmdline = 0;
-	WCHAR exepath[MAX_PATH], exe[MAX_PATH], top_level_path[MAX_PATH];
+	WCHAR exepath[MAX_PATH], exe_bup[MAX_PATH], exe[MAX_PATH], top_level_path[MAX_PATH];
 	LPWSTR cmd = NULL, exep = exe, prefix_args = NULL, basename;
 	LPWSTR working_directory = NULL;
 
@@ -729,6 +729,7 @@ int main(void)
 	/* get the installation location */
 	/* GetModuleFileName(NULL, exepath, MAX_PATH); */
 	find_exe_realpath(exepath, MAX_PATH);
+	wcscpy(exe_bup, exepath);
 	if (!PathRemoveFileSpec(exepath)) {
 		fwprintf(stderr, L"Invalid executable path: %s\n", exepath);
 		ExitProcess(1);
@@ -830,6 +831,11 @@ int main(void)
 		}
 	}
 
+	if (!wcscmp(exe_bup, exep)) {
+		fwprintf(stderr, L"BUG (fork bomb): %s\n", exep);
+		ExitProcess(1);
+	}
+
 	{
 		STARTUPINFO si;
 		PROCESS_INFORMATION pi;

@dennisameling
Copy link

dennisameling commented Feb 12, 2021

Just added some fprintf's for debugging - it doesn't even reach the code path /* Maybe we are on ARM64 but don't have the binaries? */:

Output is only

Starting initialize_top_level_path...
In while loop
Starting initialize_top_level_path...
In while loop
Starting initialize_top_level_path...
In while loop
....

So the strip_count apparently is 0 or higher

image

@dscho
Copy link
Member Author

dscho commented Feb 12, 2021

Aargh, you're right! We're calling initialize_top_level_path() only with strip_count == 1 when the basename is git.exe. Hrm. Let me think.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
There has been a report that `bin/git.exe` spawns itself over and over
again. This is clearly a bug, and to avoid it from making a user's
machine sluggish, let's error out early in that case.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
It was reported that the x86 version of Git for Windows v2.30.1 fork
bombs on ARM64. The reason is that we are looking for the ARM64
binaries, but they are not bundled in the x86 version.

Let's fall be careful before enabling ARM64 mode.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
git-wrapper.c changed, after all.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
@dscho dscho force-pushed the safer-arm64-support-for-git branch from 36a87e9 to dd83c3c Compare February 12, 2021 23:38
@dscho
Copy link
Member Author

dscho commented Feb 12, 2021

I think I've got something. If we call is_running_on_arm64() only inside initialize_top_level_path(), and do that by combining it with the check for /arm64/bin, I think we're golden. I pushed a new version; Could I bother you to test again?

dscho added a commit to dscho/git that referenced this pull request Feb 12, 2021
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
@dennisameling
Copy link

dennisameling commented Feb 12, 2021

Nice!! It works without the arm64 folder present now 🚀

Let me just double-check the case when the arm64 is present, give me a few mins...

@dennisameling
Copy link

Bingo! Also works when the arm64 binaries are present 🎉 Thanks!!

Copy link

@dennisameling dennisameling left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@dscho
Copy link
Member Author

dscho commented Feb 12, 2021

Awesome!

I also kicked off a build here: https://github.com/dscho/git/actions/runs/562531927, and intend to let the (private...) reporter test before merging.

@dscho
Copy link
Member Author

dscho commented Feb 13, 2021

let the (private...) reporter test before merging.

That test also succeeded.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants