git: 9bfd3b4076a7 - main - Add a build knob for _FORTIFY_SOURCE
Date: Mon, 13 May 2024 05:24:11 UTC
The branch main has been updated by kevans:
URL: https://cgit.FreeBSD.org/src/commit/?id=9bfd3b4076a7b0dfd27ab22318e5113dc84fea28
commit 9bfd3b4076a7b0dfd27ab22318e5113dc84fea28
Author: Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2024-05-13 05:23:50 +0000
Commit: Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2024-05-13 05:23:50 +0000
Add a build knob for _FORTIFY_SOURCE
In the future, we will Default to _FORTIFY_SOURCE=2 if SSP is enabled,
otherwise default to _FORTIFY_SOURCE=0. For now we default it to 0
unconditionally to ease bisect across older versions without the new
symbols, and we'll put out a call for testing.
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.
Reviewed by: des, markj
Relnotes: yes
Sponsored by: Stormshield
Sponsored by: Klara, Inc.
Differential Revision: https://reviews.freebsd.org/D32308
---
include/stdio.h | 3 ++
include/string.h | 3 ++
include/strings.h | 3 ++
include/unistd.h | 4 +++
lib/libthr/Makefile | 3 ++
libexec/rtld-elf/Makefile | 4 +++
share/man/man7/security.7 | 75 +++++++++++++++++++++++++++++++++++++++++
share/mk/bsd.sys.mk | 7 ++++
tools/build/options/WITHOUT_SSP | 3 ++
tools/build/options/WITH_SSP | 3 ++
10 files changed, 108 insertions(+)
diff --git a/include/stdio.h b/include/stdio.h
index fe7a6f7d6f82..30bc638082d8 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -530,4 +530,7 @@ extern int __isthreaded;
__END_DECLS
__NULLABILITY_PRAGMA_POP
+#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0
+#include <ssp/stdio.h>
+#endif
#endif /* !_STDIO_H_ */
diff --git a/include/string.h b/include/string.h
index 597308020cdb..a595f6e3e260 100644
--- a/include/string.h
+++ b/include/string.h
@@ -168,4 +168,7 @@ errno_t memset_s(void *, rsize_t, int, rsize_t);
#endif /* __EXT1_VISIBLE */
__END_DECLS
+#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0
+#include <ssp/string.h>
+#endif
#endif /* _STRING_H_ */
diff --git a/include/strings.h b/include/strings.h
index fde007186e04..6fe6a09e7dd3 100644
--- a/include/strings.h
+++ b/include/strings.h
@@ -68,4 +68,7 @@ int strncasecmp(const char *, const char *, size_t) __pure;
#endif
__END_DECLS
+#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0
+#include <ssp/strings.h>
+#endif
#endif /* _STRINGS_H_ */
diff --git a/include/unistd.h b/include/unistd.h
index e4e5c62fbb67..59738cbf6e68 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -37,6 +37,10 @@
#include <sys/_null.h>
#include <sys/_types.h>
+#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0
+#include <ssp/unistd.h>
+#endif
+
#ifndef _GID_T_DECLARED
typedef __gid_t gid_t;
#define _GID_T_DECLARED
diff --git a/lib/libthr/Makefile b/lib/libthr/Makefile
index a5bf5da44170..85c028f521a1 100644
--- a/lib/libthr/Makefile
+++ b/lib/libthr/Makefile
@@ -11,6 +11,9 @@ LDFLAGS+= -Wl,--rpath=/usr/lib${COMPAT_libcompat}
.include <src.opts.mk>
MK_SSP= no
+# SSP forced off already implies FORTIFY_SOURCE=0, but we must make sure that
+# one cannot turn it back on.
+FORTIFY_SOURCE= 0
LIB=thr
SHLIB_MAJOR= 3
diff --git a/libexec/rtld-elf/Makefile b/libexec/rtld-elf/Makefile
index 37c3840538d5..864448ad782a 100644
--- a/libexec/rtld-elf/Makefile
+++ b/libexec/rtld-elf/Makefile
@@ -15,6 +15,10 @@ MK_UBSAN= no
.include <bsd.compat.pre.mk>
+# SSP forced off already implies FORTIFY_SOURCE=0, but we must make sure that
+# one cannot turn it back on.
+FORTIFY_SOURCE= 0
+
.if !defined(NEED_COMPAT)
CONFS= libmap.conf
.endif
diff --git a/share/man/man7/security.7 b/share/man/man7/security.7
index ccbeeb4575ce..2e690e35d534 100644
--- a/share/man/man7/security.7
+++ b/share/man/man7/security.7
@@ -939,6 +939,81 @@ option that SSH allows in its
.Pa authorized_keys
file to make the key only usable to entities logging in from specific
machines.
+.Sh STACK OVERFLOW PROTECTION
+.Fx
+supports stack overflow protection using the Stack Smashing Protector
+.Pq SSP
+compiler feature.
+In userland, SSP adds a per-process randomized canary at the end of every stack
+frame which is checked for corruption upon return from the function.
+In the kernel, a single randomized canary is used globally except on aarch64,
+which has a
+.Dv PERTHREAD_SSP
+.Xr config 8
+option to enable per-thread randomized canaries.
+If stack corruption is detected, then the process aborts to avoid potentially
+malicious execution as a result of the corruption.
+SSP may be enabled or disabled when building
+.Fx
+base with the
+.Xr src.conf 5
+SSP knob.
+.Pp
+When
+.Va WITH_SSP
+is enabled, which is the default, world is built with the
+.Fl fstack-protector-strong
+compiler option.
+The kernel is built with the
+.Fl fstack-protector
+option.
+.Pp
+In addition to SSP, a
+.Dq FORTIFY_SOURCE
+implementation is supported up to level 2 by defining
+.Va _FORTIFY_SOURCE
+to
+.Dv 1
+or
+.Dv 2
+before including any
+.Fx
+headers.
+.Fx
+world builds can set
+.Va FORTIFY_SOURCE
+to provide a default value for
+.Va _FORTIFY_SOURCE .
+When enabled,
+.Dq FORTIFY_SOURCE
+enables extra bounds checking in various functions that accept buffers to be
+written into.
+These functions currently have extra bounds checking support:
+.Bl -column -offset indent "snprintf" "memmove" "strncpy" "vsnprintf" "readlink"
+.It bcopy Ta bzero Ta fgets Ta getcwd Ta gets
+.It memcpy Ta memmove Ta memset Ta read Ta readlink
+.It snprintf Ta sprintf Ta stpcpy Ta stpncpy Ta strcat
+.It strcpy Ta strncat Ta strncpy Ta vsnprintf Ta vsprintf
+.El
+.Pp
+.Dq FORTIFY_SOURCE
+requires compiler support from
+.Xr clang 1
+or
+.Xr gcc 1 ,
+which provide the
+.Xr __builtin_object_size 3
+function that is used to determine the bounds of an object.
+This feature works best at optimization levels
+.Fl O1
+and above, as some object sizes may be less obvious without some data that the
+compiler would collect in an optimization pass.
+.Pp
+Similar to SSP, violating the bounds of an object will cause the program to
+abort in an effort to avoid malicious execution.
+This effectively provides finer-grained protection than SSP for some class of
+function and system calls, along with some protection for buffers allocated as
+part of the program data.
.Sh KNOBS AND TWEAKS
.Fx
provides several knobs and tweak handles that make some introspection
diff --git a/share/mk/bsd.sys.mk b/share/mk/bsd.sys.mk
index de91e00d8cc7..52c3d07746c7 100644
--- a/share/mk/bsd.sys.mk
+++ b/share/mk/bsd.sys.mk
@@ -294,11 +294,18 @@ CFLAGS.clang+= -Qunused-arguments
# but not yet.
CXXFLAGS.clang+= -Wno-c++11-extensions
+# XXX This should be defaulted to 2 when WITH_SSP is in use after further
+# testing and soak time.
+FORTIFY_SOURCE?= 0
.if ${MK_SSP} != "no"
# Don't use -Wstack-protector as it breaks world with -Werror.
SSP_CFLAGS?= -fstack-protector-strong
CFLAGS+= ${SSP_CFLAGS}
.endif # SSP
+.if ${FORTIFY_SOURCE} > 0
+CFLAGS+= -D_FORTIFY_SOURCE=${FORTIFY_SOURCE}
+CXXFLAGS+= -D_FORTIFY_SOURCE=${FORTIFY_SOURCE}
+.endif
# Additional flags passed in CFLAGS and CXXFLAGS when MK_DEBUG_FILES is
# enabled.
diff --git a/tools/build/options/WITHOUT_SSP b/tools/build/options/WITHOUT_SSP
index 88162cecf14a..7a773fe1e5aa 100644
--- a/tools/build/options/WITHOUT_SSP
+++ b/tools/build/options/WITHOUT_SSP
@@ -1 +1,4 @@
Do not build world with stack smashing protection.
+See
+.Xr security 7
+for more information.
diff --git a/tools/build/options/WITH_SSP b/tools/build/options/WITH_SSP
index 0088dd133782..4f06a73d4173 100644
--- a/tools/build/options/WITH_SSP
+++ b/tools/build/options/WITH_SSP
@@ -1 +1,4 @@
Build world with stack smashing protection.
+See
+.Xr security 7
+for more information.