Page MenuHomeFreeBSD

Add a build knob for _FORTIFY_SOURCE
AcceptedPublic

Authored by kevans on Oct 5 2021, 3:48 AM.
Tags
None
Referenced Files
Unknown Object (File)
Mon, Apr 29, 4:52 AM
Unknown Object (File)
Sat, Apr 27, 8:27 AM
Unknown Object (File)
Fri, Apr 26, 10:13 PM
Unknown Object (File)
Fri, Apr 26, 9:39 PM
Unknown Object (File)
Fri, Apr 26, 7:46 PM
Unknown Object (File)
Sun, Apr 21, 9:57 PM
Unknown Object (File)
Wed, Apr 17, 2:56 PM
Unknown Object (File)
Tue, Apr 16, 5:31 AM

Details

Reviewers
imp
markj
Group Reviewers
Klara
Summary

Default to _FORTIFY_SOURCE=2 if SSP is enabled, otherwise default to
_FORTIFY_SOURCE=0. include/*.h include their ssp/*.h equivalents as
needed based on the knob. Programs and users are allowed to override
FORTIFY_SOURCE in their Makefiles or src.conf/make.conf to force it off.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 57113
Build 54001: arc lint + arc unit

Event Timeline

kevans requested review of this revision.Oct 5 2021, 3:48 AM

I think rtld must never be built with this thing enabled. In particular, if it references some libc symbol, then just that symbol should be used, without any wrappers.

Also I think that libthr should avoid it, but might be it is not as important as for rtld. In particular, did you checked that e.g. cancellation for read(2) still works as intended?

In D32308#729152, @kib wrote:

I think rtld must never be built with this thing enabled. In particular, if it references some libc symbol, then just that symbol should be used, without any wrappers.

Also I think that libthr should avoid it, but might be it is not as important as for rtld. In particular, did you checked that e.g. cancellation for read(2) still works as intended?

rtld was already not building with it by virtue of MK_SSP=no, but I've applied the FORTIFY_SOURCE=0 hammer as well to ensure that one can't turn it on manually when building with something like WITHOUT_SSP=yes FORTIFY_SOURCE=2.

libthr is in the same boat, but turning it on and this primitive test still seems to cancel at the beginning of the read:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

#define BUFSIZE 512

int
main(int argc, char *argv[])
{
        char buf[BUFSIZE];
        ssize_t rd;

        pthread_cancel(pthread_self());

        rd = read(STDIN_FILENO, buf, sizeof(buf));
        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
        write(STDOUT_FILENO, buf, rd);

        printf("done\n");

        exit(1);
}

(assuming the anticipated failure mode would have been interposing failed and read() was libc-read, so the cancel would fail and maybe cancel at write() thus disabling cancellation just before it)

That said, I don't feel particularly compelled to leave it to the whim of a user-knob that nobody working on libthr is going to test, so I'll force it off in the next version as it will be in rtld.

Force off for rtld/libthr

This one is OK as is, just one question...

include/unistd.h
360

isn't there a _FORTIFY_SOURCE_read or something that this could be done for? Or is the order wrong for that?

kevans marked an inline comment as done.

Drop read() declaration avoidance; whatever was causing problems before, I
cannot reproduce it today.

des added inline comments.
include/stdio.h
533
kevans marked an inline comment as done.

defined(X) && X > 0 -> X

do we have user-facing documentation? maybe just expanding WITHOUT_SSP's description?

share/mk/bsd.sys.mk
303

Do you perhaps want to force it to zero here? It can't work without SSP, can it?

share/mk/bsd.sys.mk
303

I don't believe it's inherently reliant on SSP (__builtin_object_size should work without SSP enabled) so one could turn it on and it'll DTRT; I'm mostly treating it as an extension of SSP here for convenience.

Amend WITH_SSP/WITHOUT_SSP descriptions with a note about FORTIFY_SOURCE

do we have user-facing documentation? maybe just expanding WITHOUT_SSP's description?

I wonder if it makes sense to add a section on stack overflow detection to security(7) would make sense

I wonder if it makes sense to add a section on stack overflow detection to security(7) would make sense

Yeah that sounds good

do we have user-facing documentation? maybe just expanding WITHOUT_SSP's description?

I wonder if it makes sense to add a section on stack overflow detection to security(7) would make sense

I think that'd be useful, and it'd be good to describe/summarize FORTIFY_SOURCE there as well. Then the src.conf entry for WITH_SSP can refer to it.

Document stack protections in security(7), xref from the build knobs

share/man/man7/security.7
944 ↗(On Diff #138034)

Stack Smashing Protector ?

markj added inline comments.
lib/libthr/Makefile
16

Out of curiosity, what exactly goes wrong when libthr is compiled with SSP on?

share/man/man7/security.7
948 ↗(On Diff #138035)

It is maybe worth noting here or somewhere that this option applies to the kernel as well. There it uses a global canary. And, on arm64 there is a PERTHREAD_SSP option which enables a per-thread canary.

975 ↗(On Diff #138035)

Maybe mention some example functions here, just to give the reader a bit more context.

This revision is now accepted and ready to land.Thu, May 2, 8:05 PM
kevans marked 2 inline comments as done.

Mention what happens to the kernel when SSP is enabled
Enumerate the functions with bounds checking in a fancy table

This revision now requires review to proceed.Thu, May 2, 9:33 PM
lib/libthr/Makefile
16

I'm not sure; I can play around with it a bit later after this set of stuff goes in and figure out to what extent we really need to be disabling libthr protections.

markj added inline comments.
share/man/man7/security.7
953 ↗(On Diff #138051)
This revision is now accepted and ready to land.Fri, May 3, 2:12 AM