diff --git a/include/stdio.h b/include/stdio.h --- a/include/stdio.h +++ b/include/stdio.h @@ -530,4 +530,7 @@ __END_DECLS __NULLABILITY_PRAGMA_POP +#if _FORTIFY_SOURCE +#include +#endif #endif /* !_STDIO_H_ */ diff --git a/include/string.h b/include/string.h --- a/include/string.h +++ b/include/string.h @@ -168,4 +168,7 @@ #endif /* __EXT1_VISIBLE */ __END_DECLS +#if _FORTIFY_SOURCE +#include +#endif #endif /* _STRING_H_ */ diff --git a/include/strings.h b/include/strings.h --- a/include/strings.h +++ b/include/strings.h @@ -68,4 +68,7 @@ #endif __END_DECLS +#if _FORTIFY_SOURCE +#include +#endif #endif /* _STRINGS_H_ */ diff --git a/include/unistd.h b/include/unistd.h --- a/include/unistd.h +++ b/include/unistd.h @@ -37,6 +37,10 @@ #include #include +#if _FORTIFY_SOURCE +#include +#endif + #ifndef _GID_T_DECLARED typedef __gid_t gid_t; #define _GID_T_DECLARED diff --git a/lib/libthr/Makefile b/lib/libthr/Makefile --- a/lib/libthr/Makefile +++ b/lib/libthr/Makefile @@ -11,6 +11,9 @@ .include 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 --- a/libexec/rtld-elf/Makefile +++ b/libexec/rtld-elf/Makefile @@ -15,6 +15,10 @@ .include +# 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 --- a/share/man/man7/security.7 +++ b/share/man/man7/security.7 @@ -939,6 +939,76 @@ .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. +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 --- a/share/mk/bsd.sys.mk +++ b/share/mk/bsd.sys.mk @@ -295,10 +295,19 @@ CXXFLAGS.clang+= -Wno-c++11-extensions .if ${MK_SSP} != "no" +FORTIFY_SOURCE?= 2 # Don't use -Wstack-protector as it breaks world with -Werror. SSP_CFLAGS?= -fstack-protector-strong CFLAGS+= ${SSP_CFLAGS} +.else +FORTIFY_SOURCE?= 0 .endif # SSP +.if ${FORTIFY_SOURCE} > 0 +# We default FORTIFY_SOURCE=2 if SSP is enabled, or default it to 0 without. +# The program or user can tweak it as needed. +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 --- a/tools/build/options/WITHOUT_SSP +++ b/tools/build/options/WITHOUT_SSP @@ -1 +1,7 @@ Do not build world with stack smashing protection. +This option also sets +.Ev FORTIFY_SOURCE +to 0 by default. +See +.Xr security 7 +for more information. diff --git a/tools/build/options/WITH_SSP b/tools/build/options/WITH_SSP --- a/tools/build/options/WITH_SSP +++ b/tools/build/options/WITH_SSP @@ -1 +1,7 @@ Build world with stack smashing protection. +This option also sets +.Ev FORTIFY_SOURCE +to 2 by default. +See +.Xr security 7 +for more information.