#1147712 strongswan: FTBFS with GCC 16: custom printf specifier %B rejected because -Wno-format is overridden #1147712
- Package:
- strongswan
- Source:
- strongswan
- Submitter:
- Paul Menzel
- Date:
- 2026-09-14 22:19:02 UTC
- Severity:
- normal
- Tags:
Dear Debian folks,
AI disclaimer: Analyzed and drafted by claude-opus-5, and reviewed and
edited by me.
Building strongswan with `debuild -us -uc -b` on Debian sid/unstable
with *gcc* 4:16.1.0-3 fails:
credentials/certificates/certificate_printer.c: In function
'print_x509':
credentials/certificates/certificate_printer.c:90:36: error: format
'%B' expects argument of type 'unsigned int', but argument 3 has type
'chunk_t *' [-Werror=format=]
90 | fprintf(f, " serial: %#B\n", &chunk);
| ~~^ ~~~~~~
| | |
| | chunk_t *
| unsigned int
credentials/certificates/certificate_printer.c:105:30: error:
unknown conversion type character 'Y' in format [-Werror=format=]
105 | fprintf(f, "%Y", id);
| ^
Analysis
--------
strongSwan registers custom printf conversion specifiers at runtime via
register_printf_specifier(3) – %B prints a chunk_t, %Y an
identification_t, %H a host_t and so on (see
src/libstrongswan/utils/printf_hook/printf_hook_glibc.c). GCC knows
nothing about these, so upstream’s configure.ac disables the format
warnings:
# disable some warnings, whether explicitly enabled above or by
default
# these are not compatible with our custom printf specifiers
WARN_CFLAGS="$WARN_CFLAGS -Wno-format"
WARN_CFLAGS="$WARN_CFLAGS -Wno-format-security"
[...]
# add the flags before existing CFLAGS so warning flags can be
overridden
CFLAGS="$WARN_CFLAGS $CFLAGS"
Note that these flags are *prepended*. Since d/rules sets
`DEB_BUILD_MAINT_OPTIONS=hardening=+all`, dpkg-buildflags puts
`-Wformat -Werror=format-security` into CFLAGS, i.e. after -Wno-format,
which re-enables format checking for the whole package:
x86_64-linux-gnu-gcc [...] -Wno-format -Wno-format-security [...] \
-g -O2 [...] -Wformat -Werror=format-security -fcf-protection \
-c credentials/certificates/certificate_printer.c
That has been harmless so far because GCC did not know %B either. GCC 16
does: %b/%B is C23’s conversion specifier for binary output, so GCC now
type-checks the argument and rejects the chunk_t pointer.
The runtime behavior is not affected – register_printf_specifier()
still overrides glibc’s built-in %B, verified with glibc 2.43 using a
small test program. So this is purely about the warning flags.
Proposed fix
------------
The root cause is upstream’s flag ordering: -Wno-format and
-Wno-format-security are not a style preference, they are required for
the code to compile at all, so they must not be overridable via CFLAGS.
The attached patch keeps them in a separate variable and appends it,
leaving the remaining warning flags overridable as before:
-# add the flags before existing CFLAGS so warning flags can be
overridden
-CFLAGS="$WARN_CFLAGS $CFLAGS"
+# add the flags before existing CFLAGS so warning flags can be
overridden,
+# but append those required by our custom printf specifiers so
they can't be
+# re-enabled by flags in CFLAGS
+CFLAGS="$WARN_CFLAGS $CFLAGS $PRINTF_CFLAGS"
Alternatively, or in addition, d/rules can append the flags itself,
which does not depend on the patch surviving the next upstream merge:
export DEB_CFLAGS_MAINT_APPEND=-Wno-format -Wno-format-security
With either change the package builds cleanly, including with an
additional -Werror=format in CFLAGS.
Kind regards,
Paul
severity 1147712 normal thanks [ Please note that the relevant version here would be the one in the package called "gcc-16", not "gcc", which is just the package containing the symlinkg gcc -> the-real-gcc ]. I'm attaching my build log, made a few minutes ago on current unstable. If you can still reproduce the build failure on current unstable please try building with sbuild and diff your build log with mine. Thanks.
Dear Santiago,
Thank you for your immediate reply.
Am 14.09.26 um 17:09 schrieb Santiago Vila:
[…]
It’s *gcc-16* 16.2.0-2.
claude-opus-5 found it. Upstream’s configure behaves differently, when a
directory `.git` is present, and adds `-Werror`. configure.ac:516:
# enable warnings and -Werror by default when building from the
repo (check with
# -e as .git is a file in worktrees)
if test x$warnings_given = xfalse -a -e "$srcdir"/.git; then
warnings=true
fi
then configure.ac:1401-1425:
WARN_CFLAGS=
if test x$warnings = xtrue; then
WARN_CFLAGS="-Werror -Wall -Wextra" # ← only when .git exists
fi
WARN_CFLAGS="$WARN_CFLAGS -Wno-format" # ← the suppression
lands *after* -Werror
WARN_CFLAGS="$WARN_CFLAGS -Wno-format-security"
[...]
CFLAGS="$WARN_CFLAGS $CFLAGS" # ← hardening's
-Wformat lands last and wins
`debcheckout` gives you a git tree; the buildds unpack a .dsc. That
single difference decides error vs. warning.
The warnings are also present in your log. No idea, how to proceed.
Kind regards,
Paul
This explains your build failure indeed. Packages are not required by Policy to build out of the box from a git checkout. Some maintainers aim at being able to do that, and some others do not. For example, some packages require additional build-dependencies if you want to build them from a git checkout. As I value a short build-depends list over the ability to build from a git checkout, I would not consider that to be a bug at all if it happened to me. [...] You don't have to do anything else. The maintainer (which I'm not) will decide if they want to support build from git checkout or not for this particular package. (I just downgraded the bug because this category of bugs is not considered to be release-critical). Thanks.
control: severity -1 wishlist control: tag -1 wontfix I'm not comfortable disabling this part of upstream checks. You might want to reach them to check if those could be overridden. Meanwhile, maybe try to build with a clean tree built from dpkg-source? I build using git-buildpackage and pbuilder and it does work fine here. Regards,
Dear Yves-Alexis,
Thank you for your quick response.
Am 14.09.26 um 21:45 schrieb Yves-Alexis Perez:
What checks do you mean exactly, that would get disabled? Upstream’s
configure explicitly adds `-Wno-format` [1]:
# disable some warnings, whether explicitly enabled above or by default
# these are not compatible with our custom printf specifiers
WARN_CFLAGS="$WARN_CFLAGS -Wno-format"
WARN_CFLAGS="$WARN_CFLAGS -Wno-format-security"
I don’t know these two tools, so can’t say, if they create a dedicated
build environment, so no `.git` directory is there.
Is the analysis missing anything? (In the original report the real
reason, the existence of `.git` directory, was not stated.
Kind regards,
Paul
[1]:
https://github.com/strongswan/strongswan/blob/78937d2190656f175599411c14be5ecbeb2c2c02/configure.ac#L1408-L1411
Hi. Just a minor comment: The problem you faced is not new. In Debian, as I pointed out before, some repos might build directly from a git checkout and some others might now. This is why the git-buildpackage tool exists to begin with. If you are planning to build packages after a git checkout from salsa, that's probably the recommended way (the other way is to do what Salsa CI does internally: it first creates a source package, and then it builds such source package the normal way). Thanks.