// HACKER NEWS — CYBERSECURITY
What's been going on in w64devkit the past year
The past year has been exciting for w64devkit, which like any software
distribution is never complete. Peter0x44 joined as co-maintainer, and
has pushed the project in good, new directions, with ideas I would never
have considered. Many of his improvements have gone back upstream, and so
you may benefit even if you don’t use w64devkit. I’d like to touch on the
various odds and ends from the past year.
In April I announced that release packaging is now signed. Today
all EXEs and DLLS in w64devkit are code-signed with my key. My signing
key established a good reputation thanks to thousands of unique signatures
observed on the order of ~100,000 hosts — a pleasant side effect from
including ~300 binaries in a release. Users should have fewer problems
these days with security software. MSYS2 has also adopted my signing
tool, aas-sign, which is now included in w64devkit releases.
Builds are now automated by GitHub Actions, triggered when I (and only
I) push a new tag. That process code-signs and creates the release. Every
step of the release process is transparent, derived strictly from source
in the repository. Nowhere does it go behind a curtain and permit secret
tampering.
But that’s not all. I enabled release immutability: On publish, release
artifacts are locked in and nobody, not even me, can modify them. You can
tell by the presence of a release attestation at the end of the artifacts
listing. Nobody involved in the project down the road can go rogue and
sneak something into an old release.
The x64 release is now a “multilib” toolchain. That is it can compile
programs for 32-bit Windows, like a superset of the x86 release. The only
purpose of the x86 release is to run w64devkit on older hardware or older
operating systems. Like the x86 release, it targets Windows XP by default
and requires a CPU supporting SSE2 (i.e. at least Pentium 4).
To target x86, pass -m32 when compiling and linking. Or better, use
tools prefixed with the i686-w64-mingw32 architecture triple. The latter
is easier in general because different tools require different switches,
and the prefixed tools are aliases that automatically do the right
thing.
Adding multilib was cheaper and easier than I anticipated, and it’s thanks
to Peter0x44. It’s already been convenient for me for several projects.
In the past you needed w64devkit’s bin/ on your $PATH in order to use
the compiler, because that’s how GCC found the other tools it needs. This
is no longer the case, and you can invoke path/to/gcc.exe from scripts
and such without touching your path. This required a small GCC patch.
The standard COFF object format supports up to 65,535 sections. When the
format was designed this probably seemed like more than enough, but modern
C++ programs can easily exceed it, particularly debug builds of programs
using lots of lambda functions. As C++ projects grow they eventually hit a
threshold where builds fail unless you ask for the bigobj COFF format,
which supports over 4 billion sections. This is annoying, and the tools
ought to deal with this automatically.
A couple years ago I patched Bintutils to produce bigobj by default so the
old limit would never affect a build. The catch is that Binutils lacks an
interface to request standard COFF, so you can’t downgrade if needed. Why
would you need to? When interacting some simpler linkers like the official
Go toolchain (gc)! Some linkers can’t consume bigobj. It also breaks some
builds that auto-detect the toolchain’s object format, as some detection
scripts don’t know about bigobj (ex. libbacktrace at the time).