Ubuntu -fcf-protection=full breaking code

Alex Murray alex.murray at canonical.com
Wed Feb 17 01:34:34 UTC 2021

On Tue, 2021-02-16 at 20:04:58 +1030, Matthias Klose wrote:

> On 2/15/21 3:17 AM, Alex Murray wrote:
>> Hi Michael,
>> For Ubuntu we try and take an approach where we want as much code that
>> is compiled for and *on* Ubuntu to try and take advantage of the various
>> toolchain hardening options that are available.  This gives end-users
>> the most protection with the least amount of work.
> Alex, this doesn't match my memory.  Turning on the hardening flags 
> always was a
> hack to build packages with hardening flags that ignored flags in their 
> build
> system, which are set by the packaging code.

I don't have the context for why the original decision was made back
when this was done the first time, but the above is my understanding and
rationale for why we continue to take this approach now. Also as state
below, in particular for effective cf-protection *everything* has to be
built with this enabled - are we sure this is do-able with the
buildflags or some other approach? I suspect we will always need this
kind of hack as you call it to ensure significant coverage is achieved
across the whole archive.

>> In some cases however, this can lead to issues as noted in the github
>> issue you linked to - not all compiler options will be suitable for all
>> codebases etc. However, there are a huge number of codebases which are
>> suitable for this kind of feature and automatically benefit from
>> this. Also as Ubuntu is used by a huge number of software developers and
>> is a platform of choice in CI/CD systems, this then allows many
>> codebases to automatically benefit from these default hardening
>> features. To make control-flow protection usable in practice, not only
>> does the binary need to be compiled with this enabled, but also all
>> shared libraries etc. If a user wants to compile a newer version of a
>> library, they can then simply do the usual, configure && make && make
>> install, and it will get compiled with these CFLAGS as well (whereas
>> were this done solely via dpkg-buildflags or similar, only
>> binaries/libraries shipped via debs would likely be compiled with this
>> feature which would then make it a bit pointless if some libraries have
>> it on but others do not).
>> So as with all things, there is a balance that needs to be struck
>> between the two - the current solution allows this default to be turned
>> off via CFLAGS as mentioned at
>> https://wiki.ubuntu.com/ToolChain/CompilerFlags#A-fcf-protection if
>> needed - but also ensures that as many different packages or bespoke
>> codebases will be compiled with this option on (and as such likely then
>> ensure it can be used in end-deployments as with any luck all dependent
>> libraries get compiled with it on as well).
> The current "balance" is to force things into GCC first, and then tending 
> to
> ignore or delay any follow-up work.  -fcf-protection and
> -fstack-clash-protection don't show up in build logs for package builds, 
> so at
> least for package builds, package maintainers don't easily see which 
> hardening
> flags are in use.

The omission of clang and other compilers is a good point and I agree we
should be trying to ensure we use the same default compiler flags for
all compilers which support them. At this stage however, the use of gcc
still outweighs other compilers significantly, probably not least
because build-essential depends on gcc not clang. But especially in
light of the want to have as full coverage of the archive as possible
for effective cf-protection, we should make it a priority to ensure
clang and others are supported as well.

> Software built by other compilers doesn't take "advantage of the various
> toolchain hardening options", so I think your claim made in the first 
> paragraph
> is at least misleading.

This is true but again I would say the usage of clang or other compilers
on Ubuntu is a lot smaller than gcc - so by targetting gcc with these
features we get the majority of users.

> Non-package builds don't see any of these hardening
> options, as well as packages ignoring options set in the build 
> environment.
> Even packages respecting their build environment don't see 
> -fcf-protection and
> -fstack-clash-protection at all.

Whilst you don't see these compiler flags in the build output, they are
still on - so these non-package builds etc still benefit from
them. There are also many other compiler flags which are implicitly
enabled but which don't get shown on the command-line or similar when
you compile things - should we be expecting to surface these as well?

> Users are also happy using these compilers to
> work around the Ubuntu GCC settings with the least amount of work.

I am confused - above you seem to suggest that the omission of these
flags from other compilers is something that should be addressed as a
current shortcoming - but this sentence seems to advocate for not doing
this as a workaround for the current default-on implementation.

I am more than happy to revisit how we implement the default compiler
options for enabling various toolchain hardening features in Ubuntu but
I want to make sure we are all working from the same set of requirements
in the first place. I feel the current implementation, whilst not
perfect and clearly with gaps re clang etc, achieves a good balance and
outcome for our users, but I am more than willing to do this in a
different way if you feel there is a better solution (and time
permitting, to try and get clang etc supported as well).

> Matthias
>> Thanks,
>> Alex
>> On Tue, 2021-02-09 at 05:40:40 +1030, michael Bostwick wrote:
>>> Any idea why
>>> Overriding the default flags to include -fcf-protection=full breaks 
>>> ipxe,
>>> and other tooling not coded to work around it as can be seen on github:
>>> https://github.com/ipxe/ipxe/commit/e8393c3728bf7073d033410373ef6781549c7c3e#commitcomment-46894324
>>> There is an easier and more straightforward work around (preferred 
>>> within the package build), why not use that ?

More information about the Ubuntu-devel-discuss mailing list