diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2005941571..6a1135383a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -34,14 +34,19 @@ jobs: git ls-files \*/PKGBUILD | sed 's|[^/]*$||' | sort >directories.txt && define_matrix matrix directories.txt touched.txt packages.txt && - git ls-files \*/release.sh | sed 's|[^/]*$||' | sort >releaseable.txt && - define_matrix artifacts releaseable.txt touched.txt artifacts.txt - test -z "$(git log -L :create_sdk_artifact:please.sh ${{github.event.pull_request.base.sha}}.. -- )" && - test 200 -gt $(git diff --numstat ${{github.event.pull_request.base.sha}}.. -- please.sh | cut -f 2) && + test 200 -gt $(($(git diff --numstat ${{github.event.pull_request.base.sha}}.. -- please.sh | cut -f 2))) && test -z "$(git diff ${{github.event.pull_request.base.sha}}.. -- make-file-list.sh)" || echo "test-sdk-artifacts=true" >>$GITHUB_OUTPUT + git ls-files \*/release.sh | sed 's|[^/]*$||' | sort >releaseable.txt && + if grep -q test-sdk-artifacts=true $GITHUB_OUTPUT + then + # These are already tested as part of the `sdk-artifacts` matrix + sed -i '/^\(installer\|mingit\)\/$/d' releaseable.txt + fi && + define_matrix artifacts releaseable.txt touched.txt artifacts.txt + test -z "$(git diff ${{github.event.pull_request.base.sha}}.. -- check-for-missing-dlls.sh)" || echo "check-for-missing-dlls=true" >>$GITHUB_OUTPUT outputs: @@ -63,6 +68,7 @@ jobs: with: flavor: full - name: build ${{ matrix.directory }} + id: build shell: bash run: | top_dir=$PWD && @@ -71,11 +77,11 @@ jobs: artifacts="$(basename "${{ matrix.directory }}")-artifacts" && mkdir -p "$top_dir/$artifacts" && mv *.tar.* "$top_dir/$artifacts"/ && - echo "artifacts=$artifacts" >>$GITHUB_ENV + echo "results=$artifacts" >>$GITHUB_OUTPUT - uses: actions/upload-artifact@v3 with: - name: ${{ env.artifacts }} - path: ${{ env.artifacts }} + name: ${{ steps.build.outputs.result }} + path: ${{ steps.build.outputs.result }} - name: ensure that the Git worktree is still clean shell: bash run: | @@ -117,15 +123,48 @@ jobs: echo "MSYSTEM=MINGW64" >>$GITHUB_ENV - name: build ${{ matrix.directory }}/ shell: bash + id: build run: | artifacts="$(basename "${{ matrix.directory }}")-artifacts" && mkdir -p "$artifacts" && ./"${{ matrix.directory }}"/release.sh --output="$PWD/$artifacts/" 0-test && - echo "artifacts=$artifacts" >>$GITHUB_ENV + echo "result=$artifacts" >>$GITHUB_OUTPUT - uses: actions/upload-artifact@v3 with: - name: ${{ env.artifacts }} - path: ${{ env.artifacts }} + name: ${{ steps.build.outputs.result }} + path: ${{ steps.build.outputs.result }} + - name: run the installer + if: matrix.directory == 'installer' + shell: pwsh + run: | + $exePath = Get-ChildItem -Path ${{ steps.build.outputs.result }}/*.exe | %{$_.FullName} + $installer = Start-Process -PassThru -Wait -FilePath "$exePath" -ArgumentList "/SILENT /VERYSILENT /NORESTART /SUPPRESSMSGBOXES /ALLOWDOWNGRADE=1 /ALLOWINSTALLING32ON64=1 /LOG=installer.log" + $exitCode = $installer.ExitCode + if ($exitCode -ne 0) { + Write-Host "::error::Installer failed with exit code $exitCode!" + exit 1 + } + "$env:ProgramFiles\Git\usr\bin" | Out-File -Encoding ascii -Append $env:GITHUB_PATH + "$env:ProgramFiles\Git\mingw64\bin" | Out-File -Encoding ascii -Append $env:GITHUB_PATH + - name: show installer log + # run this even if the installation failed (actually, _in particular_ when the installation failed) + if: always() && matrix.directory == 'installer' + shell: bash + run: cat installer.log + - name: validate + if: matrix.directory == 'installer' + shell: bash + run: | + set -x && + grep 'Installation process succeeded' installer.log && + ! grep -iw failed installer.log && + cygpath -aw / && + git.exe version --build-options >version && + cat version && + checklist=installer/run-checklist.sh && + # cannot test SSH keys in read-only mode, skip test for now + sed -i 's|git@ssh.dev.azure.com:v3/git-for-windows/git/git|https://github.com/git/git|' $checklist && + sh -x $checklist sdk-artifacts: needs: determine-packages if: needs.determine-packages.outputs.test-sdk-artifacts == 'true' @@ -197,16 +236,17 @@ jobs: "${env:ProgramFiles(x86)}\Git\mingw32\bin" | Out-File -Encoding ascii -Append $env:GITHUB_PATH } else { "$env:ProgramFiles\Git\usr\bin" | Out-File -Encoding ascii -Append $env:GITHUB_PATH - "$env:ProgramFiles\Git\mingw${{env.ARCH_BITNESS}}\bin" | Out-File -Encoding ascii -Append $env:GITHUB_PATH + "$env:ProgramFiles\Git\mingw${{ matrix.bitness }}\bin" | Out-File -Encoding ascii -Append $env:GITHUB_PATH } + - name: show installer log + # run this even if the installation failed (actually, _in particular_ when the installation failed) + if: always() && matrix.artifact == 'build-installers' + shell: bash + run: cat installer.log - name: validate if: matrix.artifact == 'build-installers' shell: bash run: | - echo '::group::installer.log' - cat installer.log - echo '::endgroup' - set -x && grep 'Installation process succeeded' installer.log && ! grep -iw failed installer.log && diff --git a/aslr-manager.ps1 b/aslr-manager.ps1 new file mode 100644 index 0000000000..608a796fd6 --- /dev/null +++ b/aslr-manager.ps1 @@ -0,0 +1,23 @@ +param( + [Parameter(Mandatory = $true, HelpMessage="Enable or disable mandatory ASLR for the target executables.")][ValidateSet('Enable', 'Disable')][string]$Action, + [Parameter(mandatory=$true, ValueFromRemainingArguments=$true, HelpMessage="The paths of the target executables.")][string[]]$paths +) + +# Define a string array that will hold the target executable paths. +$targets = @() + +# Parse the target executable paths. +$paths | ForEach-Object { + if (Test-Path -Path "$_" -PathType Container) { + Get-ChildItem -Path "$_" -Filter *.exe -File | ForEach-Object { $targets += $_.FullName } + } + elseif (Test-Path -Path "$_" -PathType File -Filter *.exe) { + $targets += (Get-ChildItem -Path "$_" -File).FullName + } + else { + throw New-Object ArgumentException("The path `"$_`" provided is not valid!") + } +} + +# Configure the security settings for each executable in the targets array. +$targets | ForEach-Object { Invoke-Expression "Set-ProcessMitigation -Name `"$_`" -$Action ForceRelocateImages" } diff --git a/installer/install.iss b/installer/install.iss index 6866b505f1..7f590c1900 100644 --- a/installer/install.iss +++ b/installer/install.iss @@ -131,6 +131,7 @@ Source: {#SourcePath}\NOTICE.txt; DestDir: {app}; Flags: replacesameversion; Aft #ifdef INCLUDE_EDIT_GIT_BASH Source: {#SourcePath}\..\edit-git-bash.exe; Flags: dontcopy #endif +Source: "{#SourcePath}\..\aslr-manager.ps1"; DestName: aslr-manager.ps1; DestDir: {app}\cmd; Flags: replacesameversion restartreplace [Dirs] Name: "{app}\dev" @@ -387,6 +388,9 @@ const GP_FSCache = 1; GP_Symlinks = 2; + // Security options + SO_MandatoryASLR = 1; + #ifdef WITH_EXPERIMENTAL_BUILTIN_DIFFTOOL #define HAVE_EXPERIMENTAL_OPTIONS 1 #endif @@ -496,6 +500,9 @@ var ExtraOptionsPage:TWizardPage; RdbExtraOptions:array[GP_FSCache..GP_Symlinks] of TCheckBox; + SecurityOptionsPage:TWizardPage; + RdbSecurityOptions:array[SO_MandatoryASLR..SO_MandatoryASLR] of TCheckBox; + #ifdef HAVE_EXPERIMENTAL_OPTIONS // Wizard page and variables for the experimental options. ExperimentalOptionsPage:TWizardPage; @@ -1797,6 +1804,7 @@ var BtnPlink:TButton; Data:String; LblInfo:TLabel; + AslrSetting: AnsiString; begin InferredDefaultKeys:=TStringList.Create; InferredDefaultValues:=TStringList.Create; @@ -2344,6 +2352,17 @@ begin RdbExtraOptions[GP_Symlinks].Checked:=Data<>'Disabled'; +#ifdef DEBUG_WIZARD_PAGE + if ('{#DEBUG_WIZARD_PAGE}'='SecurityOptionsPage.ID') then begin +#else + if RegQueryBinaryValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager\kernel', 'MitigationOptions', AslrSetting) and + (Length(AslrSetting)>1) and (AslrSetting[2]=AnsiChar(#01)) then begin +#endif + SecurityOptionsPage:=CreatePage(PrevPageID,'Security options','Add mandatory ASLR security exceptions?',TabOrder,Top,Left); + RdbSecurityOptions[SO_MandatoryASLR]:=CreateCheckBox(SecurityOptionsPage, 'Add mandatory ASLR security exceptions','Add mandatory ASLR security exceptions for the executables in the "usr/bin"'+#13+'directory and Git Bash to function correctly on Windows systems with'+#13+'mandatory ASLR enabled which is a Windows security feature that is'+#13+'disabled by default but appears to be enabled on your system.'+#13++#13+'WARNING: If you have installed Git to a path modifiable by an unprivileged user'+#13+'or an external drive this will add mandatory ASLR security exceptions for'+#13+'those paths on which could introduce a security vulnerability!'+#13++#13+'WARNING: Doing this significantly slows down the load time of the program'+#13+'settings list in the exploit protection section of the Windows security application'+#13+'but it will load eventually!',TabOrder,Top,Left); + RdbSecurityOptions[SO_MandatoryASLR].Checked:=ReplayChoice('Add mandatory ASLR security exceptions','Auto')='Enabled'; + end; + #ifdef HAVE_EXPERIMENTAL_OPTIONS (* * Create a custom page for experimental options. @@ -3150,6 +3169,12 @@ begin Configure experimental options } + if (SecurityOptionsPage<>Nil) then begin + WizardForm.StatusLabel.Caption:='Configuring security' + if RdbSecurityOptions[SO_MandatoryASLR].checked then + Exec('powershell.exe', ExpandConstant('-ExecutionPolicy Bypass -File "{app}/cmd/aslr-manager.ps1" -Action Disable "usr/bin"'), ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, i); + end; + WizardForm.StatusLabel.Caption:='Configuring experimental options'; #ifdef WITH_EXPERIMENTAL_BUILTIN_DIFFTOOL if RdbExperimentalOptions[GP_BuiltinDifftool].checked then @@ -3590,6 +3615,15 @@ begin end; RecordChoice(PreviousDataKey,'Enable Symlinks',Data); + // Security options. + if (SecurityOptionsPage<>Nil) then begin + Data:='Disabled'; + if RdbSecurityOptions[SO_MandatoryASLR].Checked then begin + Data:='Enabled'; + end; + RecordChoice(PreviousDataKey,'Add Mandatory ASLR security exceptions',Data); + end; + // Experimental options. #ifdef WITH_EXPERIMENTAL_BUILTIN_DIFFTOOL Data:='Disabled'; diff --git a/make-file-list.sh b/make-file-list.sh index 7a94fc9168..a80ed3bd01 100755 --- a/make-file-list.sh +++ b/make-file-list.sh @@ -84,7 +84,9 @@ fi # Newer `git.exe` no longer link to `libssp-0.dll` that has been made obsolete # by recent GCC updates EXCLUDE_LIBSSP= -grep -q libssp "/$MSYSTEM_LOWER/bin/git.exe" || EXCLUDE_LIBSSP='\|ssp' +test ! -f "/$MSYSTEM_LOWER/bin/git.exe" || +grep -q libssp "/$MSYSTEM_LOWER/bin/git.exe" || +EXCLUDE_LIBSSP='\|ssp' this_script_dir="$(cd "$(dirname "$0")" && pwd -W)" || die "Could not determine this script's dir"