Skip to content

Conversation

@dscho
Copy link
Member

@dscho dscho commented Oct 2, 2025

Third parties commonly code-sign the MSYS2 runtime when ingesting MinGit, as a way to attest the integrity (not to testify that they have vetted all the supply chain!).

This is currently broken, failing with:

SignTool Error: SignedCode::Sign returned error: 0x800700C1

  %1 is not a valid Win32 application.

SignTool Error: An error occurred while attempting to sign: msys-2.0.dll

The reason is that the MSYS toolchain's version of strip.exe somehow changes the structure of the output files that are incompatible with signtool.exe, as had been identified in ffd1140 (bash: avoid stripping after code-signing, 2022-05-02).

Therefore, as of 667799c (msys2-runtime: strip it, 2022-12-19), the msys-2.0.dll file (and all of the Cygwin utilities like cygwin-console-helper.exe) can no longer be signed.

So let's revert that change.

However, we must be very careful not to regress on the cause for that commit: It was triggered by Cygwin's build process all of a sudden including all the debug information in the msys-2.0.dll file, which makes it roughly 10x larger (and it already weighs ~3MB to begin with).

The saving grace is the -g0 part of the CFLAGS/CXXFLAGS that are hard-coded in the PKGBUILD file. This prevents debug information from being generated in th first place.

This fixes git-for-windows/git#5852

@dscho dscho self-assigned this Oct 2, 2025
@dscho
Copy link
Member Author

dscho commented Oct 2, 2025

To verify that this works, I need to:

  • compare the file sizes of this PR build to the ones from the previous build
  • try to code-sign the result locally myself

@dscho
Copy link
Member Author

dscho commented Oct 2, 2025

The saving grace is the -g0 part of the CFLAGS/CXXFLAGS that are hard-coded in the PKGBUILD file. This prevents debug information from being generated in th first place.

Sadly, this seems not to be the case, actually:

name before after
msys2-packages artifact 2.27 MB 9.2 MB
msys-2.0.dll 3,356,274 bytes 20,482,172 bytes

The msys-2.0.dll contents, according to 7-Zip's extractor:

before after
image image

@dscho
Copy link
Member Author

dscho commented Oct 2, 2025

CFLAGS used for building

According to the log, these CFLAGS were used:

make "CC_FOR_BUILD=gcc" "CFLAGS=-g -O2 -pipe -g0 -Wno-error=deprecated -Wno-error=stringop-truncation -Wno-error=missing-attributes -Wno-error=maybe-uninitialized -DCYGPORT_RELEASE_INFO=3.6.4" "CCASFLAGS=-g -O2 -pipe -g0 -Wno-error=deprecated -Wno-error=stringop-truncation -Wno-error=missing-attributes -Wno-error=maybe-uninitialized -DCYGPORT_RELEASE_INFO=3.6.4" "CFLAGS_FOR_BUILD=-O2 -pipe -g0 -Wno-error=deprecated -Wno-error=stringop-truncation -Wno-error=missing-attributes -Wno-error=maybe-uninitialized -DCYGPORT_RELEASE_INFO=3.6.4" "CFLAGS_FOR_TARGET=-g -O2 -pipe -g0 -Wno-error=deprecated -Wno-error=stringop-truncation -Wno-error=missing-attributes -Wno-error=maybe-uninitialized -DCYGPORT_RELEASE_INFO=3.6.4" "INSTALL=/usr/bin/install -c" "LDFLAGS=" "LIBCFLAGS=-g -O2 -pipe -g0 -Wno-error=deprecated -Wno-error=stringop-truncation -Wno-error=missing-attributes -Wno-error=maybe-uninitialized -DCYGPORT_RELEASE_INFO=3.6.4" "LIBCFLAGS_FOR_TARGET=-g -O2 -pipe -g0 -Wno-error=deprecated -Wno-error=stringop-truncation -Wno-error=missing-attributes -Wno-error=maybe-uninitialized -DCYGPORT_RELEASE_INFO=3.6.4" "MAKE=make" "MAKEINFO=makeinfo --split-size=5000000 --split-size=5000000 " "PICFLAG=" "PICFLAG_FOR_TARGET=" "SHELL=/bin/sh" "EXPECT=expect" "RUNTEST=runtest" "RUNTESTFLAGS=" "exec_prefix=/usr" "infodir=/usr/share/info" "libdir=/usr/lib" "prefix=/usr" "tooldir=/usr/x86_64-pc-cygwin" "top_toollibdir=/usr/x86_64-pc-cygwin/lib" "AR=ar " "AS=as" "CC=gcc -L/d/a/MSYS2-packages/MSYS2-packages/msys2-runtime/src/build-x86_64-pc-cygwin/x86_64-pc-cygwin/winsup/cygwin -isystem /d/a/MSYS2-packages/MSYS2-packages/msys2-runtime/src/msys2-runtime/winsup/cygwin/include -B/d/a/MSYS2-packages/MSYS2-packages/msys2-runtime/src/build-x86_64-pc-cygwin/x86_64-pc-cygwin/newlib/ -isystem /d/a/MSYS2-packages/MSYS2-packages/msys2-runtime/src/build-x86_64-pc-cygwin/x86_64-pc-cygwin/newlib/targ-include -isystem /d/a/MSYS2-packages/MSYS2-packages/msys2-runtime/src/msys2-runtime/newlib/libc/include -I/d/a/MSYS2-packages/MSYS2-packages/msys2-runtime/src/msys2-runtime/newlib/../winsup/cygwin/include" "LD=/usr/lib/gcc/x86_64-pc-cygwin/15.2.0/../../../../x86_64-pc-cygwin/bin/ld.exe" "LIBCFLAGS=-g -O2 -pipe -g0 -Wno-error=deprecated -Wno-error=stringop-truncation -Wno-error=missing-attributes -Wno-error=maybe-uninitialized -DCYGPORT_RELEASE_INFO=3.6.4" "NM=nm" "PICFLAG=" "RANLIB=ranlib " "DESTDIR=" all-am

I cannot find an instance of -g being specified without -g0 being specified (except for the GOFLAGS, which don't matter in this context).

dscho added 2 commits October 2, 2025 13:24
A couple of those need to remain, but many of them are just oversights.

Signed-off-by: Johannes Schindelin <[email protected]>
Third parties commonly code-sign the MSYS2 runtime when ingesting
MinGit, as a way to attest the integrity (_not_ to testify that they
have vetted all the supply chain!).

This is currently broken, failing with:

  SignTool Error: SignedCode::Sign returned error: 0x800700C1

    %1 is not a valid Win32 application.

  SignTool Error: An error occurred while attempting to sign: msys-2.0.dll

The reason is that the MSYS toolchain's version of `strip.exe` somehow
changes the structure of the output files that are incompatible with
`signtool.exe`, as had been identified in ffd1140 (bash: avoid
stripping after code-signing, 2022-05-02).

Therefore, as of 667799c (msys2-runtime: strip it, 2022-12-19), the
`msys-2.0.dll` file (and all of the Cygwin utilities like
`cygwin-console-helper.exe`) can no longer be signed.

So let's revert that change.

However, we _must_ be _very_ careful not to regress on the cause for
that commit: It was triggered by Cygwin's build process all of a sudden
including all the debug information in the `msys-2.0.dll` file, which
makes it roughly 10x larger (and it already weighs ~3MB to begin with).

The saving grace is that we can put `-g0` into the `CFLAGS`/`CXXFLAGS`
variables that are hard-coded in the `PKGBUILD` file. This prevents
debug information from being generated in th first place, hence avoiding
the need to strip the executables.

Signed-off-by: Johannes Schindelin <[email protected]>
@dscho dscho force-pushed the allow-msys2-runtime-to-be-code-signed-again branch from b9b7088 to 745e6ae Compare October 2, 2025 11:41
@dscho
Copy link
Member Author

dscho commented Oct 2, 2025

I think I figured it out: while this line added the -g0 flag:

  CXXFLAGS="$OPTIM -pipe -g0 -Wno-error=deprecated -Wno-error=stringop-truncation -Wno-error=missing-attributes -Wno-error=maybe-uninitialized" #-Wno-error=class-memaccess

this line:

  export CXXFLAGS="-Wno-error -Wno-narrowing"

overrode that ;-)

@dscho
Copy link
Member Author

dscho commented Oct 2, 2025

Now we're talking:

name before after
msys2-packages artifact 2.27 MB 3.54 MB
msys-2.0.dll 3,356,274 bytes 4,076,428 bytes

The msys-2.0.dll contents, according to 7-Zip's extractor:

before after
image image

The difference is clearly dominated by the _COFF_SYMBOLS, which are no longer stripped.

Since `strip.exe` apparently does not do what we want (namely, produce a
`.dll` that can then be code-signed using `signtool.exe`), we are now
left with an `msys-2.0.dll` that -- despite containing no debug symbols
because we just suppressed them with the `-g0` flag -- still is larger
than before. The difference is essentially explained by the new
`COFF_SYMBOLS` section that had not been there before:

  $ 7z l new-msys-2.0.dll | grep COFF
  2025-10-02 15:08:52 .....       768106       768106  COFF_SYMBOLS

Since there is already an `objcopy` invocation (that uses the short-hand
`-g` for `--strip-debug`), let's just piggy-back on that invocation by
extending it with the `--strip-unneeded` option. While at it, use the
long-hand instead of the otherwise potentially puzzling `-g`.

Note: I have tried `objcopy --remove-section COFF_SYMBOLS`, but
apparently those symbols are not even a _real_ section; They live in the
PE header and hence cannot be removed via `--remove-section`.

Since this `objcopy` invocation might seem to do nothing else than
`strip.exe` (and hence potentially breaking code-signing again), I have
verified manually that the resulting `.dll` can be code-signed using
both `signtool.exe` and `osslsigncode.exe`, so all is good.

Signed-off-by: Johannes Schindelin <[email protected]>
@dscho
Copy link
Member Author

dscho commented Oct 2, 2025

And now we're cooking:

name before after
msys2-packages artifact 2.27 MB 3.4 MB
msys-2.0.dll 3,356,274 bytes 3,360,351 bytes

The msys-2.0.dll contents, according to 7-Zip's extractor:

before after
image image

The _COFF_SYMBOLS are still there, but their size is now negligible.

@dscho dscho marked this pull request as ready for review October 2, 2025 13:47
@dscho dscho requested review from mjcheetham and rimrul October 2, 2025 13:47
Copy link
Member

@mjcheetham mjcheetham left a comment

Choose a reason for hiding this comment

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

Thanks for the thorough analysis and commit messages explaining the issue here!

@dscho
Copy link
Member Author

dscho commented Oct 2, 2025

/deploy msys2-runtime

The workflow run was started.

@dscho dscho merged commit ad9f92a into main Oct 2, 2025
4 checks passed
@dscho dscho deleted the allow-msys2-runtime-to-be-code-signed-again branch October 2, 2025 21:35
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.

Allow 3rd parties to code-sign the MSYS2 runtime again

3 participants