#1147712 strongswan: FTBFS with GCC 16: custom printf specifier %B rejected because -Wno-format is overridden

Package:
strongswan
Source:
strongswan
Submitter:
Paul Menzel
Date:
2026-09-14 22:19:02 UTC
Severity:
normal
Tags:
#1147712#5
Date:
2026-09-14 14:48:40 UTC
From:
To:
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

#1147712#10
Date:
2026-09-14 15:09:30 UTC
From:
To:
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.

#1147712#17
Date:
2026-09-14 16:19:32 UTC
From:
To:
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

#1147712#22
Date:
2026-09-14 16:58:18 UTC
From:
To:
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.

#1147712#27
Date:
2026-09-14 19:45:09 UTC
From:
To:
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,

#1147712#36
Date:
2026-09-14 21:32:51 UTC
From:
To:
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

#1147712#43
Date:
2026-09-14 22:17:32 UTC
From:
To:
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.