mirror of
https://github.com/opnsense/src.git
synced 2026-06-11 01:30:30 -04:00
Add option to clear caller-used registers on function return.
The WITH_ZEROREGS option for src.conf will zero caller-used register
contents just before returning from a function, ensuring that
temporary values are not leaked beyond the function boundary. This
means that register contents are less likely to be available for side
channel attacks and information exposures.
It reduces all except 1 of the simple "write-what-where" ROP gadgets in
/lib:
grep "Gadget found" /tmp/before_lib* | wc -l
197
grep "Gadget found" /tmp/after_lib* | wc -l
1
grep "Gadget found" /tmp/after_lib*
/tmp/after_libbsdxml.so.4.txt: [+] Gadget found: 0x1b3f1 mov qword ptr [rdi], rcx ; pop rbp ; ret
To reproduce:
for lib in *.so.*; do
echo $lib:
ROPgadget --ropchain --binary /tmp/be_mount.Sx87/lib/$lib | sed -n '/Step 1/,/Step 2/p' >! /tmp/before_$lib.txt
ROPgadget --ropchain --binary $lib | sed -n '/Step 1/,/Step 2/p' >! /tmp/after_$lib.txt
done
Additionally, in some cases this reduces the number of all ROP gadgets
(quick check with /libs only):
libalias.so.7: reduction 10.000%
libavl.so.2: reduction 13.900%
libbsdxml.so.4: reduction 37.500%
libc.so.7: reduction 10.000%
libc++.so.1: reduction 14.800%
libcam.so.7: reduction 50.700%
libcap_netdb.so.1: reduction 5.800%
libcasper.so.1: reduction 14.600%
libcrypto.so.30: reduction 7.500%
libdtrace.so.2: reduction 3.900%
libelf.so.2: reduction 15.800%
libgcc_s.so.1: reduction 32.700%
libibverbs.so.1: reduction 5.300%
libicp.so.3: reduction 2.100%
libipt.so.0: reduction 28.200%
libirdma.so.1: reduction 1.600%
libkiconv.so.4: reduction 0%
libm.so.5: reduction 21.900%
libmd.so.6: reduction 0%
libmd.so.7: reduction 3.100%
libncursesw.so.9: reduction 11.200%
libnvpair.so.2: reduction 40.200%
libpcap.so.8: reduction 11.400%
libpjdlog.so.0: reduction 27.400%
libsbuf.so.6: reduction 2.900%
libspl.so.2: reduction 42.300%
libsys.so.7: reduction 2.700%
libthr.so.3: reduction 21.000%
libuutil.so.2: reduction 13.100%
libz.so.6: reduction 5.600%
libzpool.so.2: reduction 15.100%
In some cases it adds some ROP gadgets despite removing the simple ROP
gadgets:
lib80211.so.1: reduction -32.700%
libbe.so.1: reduction -22.300%
libbegemot.so.4: reduction -20.500%
libcap_dns.so.2: reduction -58.000%
libcap_fileargs.so.1: reduction -28.200%
libcap_grp.so.1: reduction -54.000%
libcap_net.so.1: reduction -28.800%
libcap_pwd.so.1: reduction -38.800%
libcap_sysctl.so.2: reduction -71.100%
libcap_syslog.so.1: reduction -15.000%
libcrypt.so.5: reduction -14.600%
libctf.so.2: reduction -.300%
libcxxrt.so.1: reduction -14.000%
libdevstat.so.7: reduction -1.600%
libedit.so.8: reduction -4.200%
libgeom.so.5: reduction -16.500%
libicp_rescue.so.3: reduction -2.300%
libipsec.so.4: reduction -31.800%
libjail.so.1: reduction -21.700%
libkvm.so.7: reduction -5.300%
libmlx5.so.1: reduction -6.300%
libmt.so.5: reduction -23.000%
libnv.so.1: reduction -.400%
librss.so.1: reduction -3.800%
librt.so.1: reduction -24.000%
libssp.so.0: reduction -21.100%
libstats.so.0: reduction -9.000%
libtinfow.so.9: reduction -3.500%
libtpool.so.2: reduction -36.500%
libufs.so.8: reduction -11.900%
libulog.so.0: reduction -67.400%
libumem.so.2: reduction -2.000%
libutil.so.9: reduction -7.200%
libxo.so.0: reduction -9.000%
libzdb.so.2: reduction -11.700%
libzfs_core.so.2: reduction -17.700%
libzfs.so.4: reduction -.300%
libzfsbootenv.so.1: reduction -26.900%
libzutil.so.2: reduction -5.600%
To reproduce:
for lib in *.so.*; do
echo -n $lib:
before="$(ROPgadget --nosys --nojop --binary /tmp/be_mount.Sx87/lib/$lib | tail -n1 | cut -d : -f 2)"
after="$(ROPgadget --nosys --nojop --binary $lib | tail -n1 | cut -d : -f 2)"
echo " reduction" $(bc -S 3 -e "(1-${after}/${before})*100")%
done >/tmp/reduction.txt
Most of the time the size difference is very small (<1% for >50% of the
files and >10% for only 2 files):
lib80211.so.1: size change .100%
libalias.so.7: size change 0%
libavl.so.2: size change 0%
libbe.so.1: size change .100%
libbegemot.so.4: size change .100%
libbsdxml.so.4: size change 0%
libc.so.7: size change 1.200%
libc++.so.1: size change 1.600%
libcam.so.7: size change 1.900%
libcap_dns.so.2: size change .100%
libcap_fileargs.so.1: size change .100%
libcap_grp.so.1: size change .100%
libcap_net.so.1: size change .100%
libcap_netdb.so.1: size change .100%
libcap_pwd.so.1: size change .100%
libcap_sysctl.so.2: size change .100%
libcap_syslog.so.1: size change .100%
libcasper.so.1: size change 0%
libcrypt.so.5: size change 3.900%
libcrypto.so.30: size change 1.400%
libctf.so.2: size change .100%
libcxxrt.so.1: size change .100%
libdevstat.so.7: size change 15.400% exceptional
libdtrace.so.2: size change .600%
libedit.so.8: size change 1.800%
libelf.so.2: size change .100%
libgcc_s.so.1: size change 3.000%
libgeom.so.5: size change 0%
libibverbs.so.1: size change .100%
libicp_rescue.so.3: size change .100%
libicp.so.3: size change 1.500%
libipsec.so.4: size change .100%
libipt.so.0: size change 3.100%
libirdma.so.1: size change .100%
libjail.so.1: size change .100%
libkiconv.so.4: size change .100%
libkvm.so.7: size change .100%
libm.so.5: size change 1.700%
libmd.so.6: size change 0%
libmd.so.7: size change .100%
libmlx5.so.1: size change 0%
libmt.so.5: size change .100%
libncursesw.so.9: size change 1.900%
libnv.so.1: size change 4.300%
libnvpair.so.2: size change 4.300%
libpcap.so.8: size change 1.200%
libpjdlog.so.0: size change .100%
librss.so.1: size change .200%
librt.so.1: size change .100%
libsbuf.so.6: size change .100%
libspl.so.2: size change 0%
libssp.so.0: size change .100%
libstats.so.0: size change .100%
libsys.so.7: size change .100%
libthr.so.3: size change 2.400%
libtinfow.so.9: size change 1.600%
libtpool.so.2: size change .100%
libufs.so.8: size change .100%
libulog.so.0: size change .100%
libumem.so.2: size change 54.300% exceptional
libutil.so.9: size change .100%
libuutil.so.2: size change .100%
libxo.so.0: size change .100%
libz.so.6: size change .100%
libzdb.so.2: size change .300%
libzfs_core.so.2: size change .100%
libzfs.so.4: size change 2.000%
libzfsbootenv.so.1: size change .100%
libzpool.so.2: size change 1.200%
libzutil.so.2: size change 0%
This commit is contained in:
parent
9dcb984251
commit
2a44cccd40
8 changed files with 39 additions and 2 deletions
|
|
@ -1,5 +1,5 @@
|
|||
.\" DO NOT EDIT-- this file is @generated by tools/build/options/makeman.
|
||||
.Dd November 22, 2024
|
||||
.Dd January 22, 2025
|
||||
.Dt SRC.CONF 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
|
@ -1856,6 +1856,11 @@ Build
|
|||
without support for the IEEE 802.1X protocol and without
|
||||
support for EAP-PEAP, EAP-TLS, EAP-LEAP, and EAP-TTLS
|
||||
protocols (usable only via 802.1X).
|
||||
.It Va WITH_ZEROREGS
|
||||
Build the basesystem with code to zero caller-used register contents
|
||||
on function return.
|
||||
This prevents leaking temporary values for side channel attacks.
|
||||
Additionally this reduces the number of usable ROP gadgets for attackers.
|
||||
.It Va WITHOUT_ZFS
|
||||
Do not build the ZFS file system kernel module, libraries such as
|
||||
.Xr libbe 3 ,
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
# - retpoline: supports the retpoline speculative execution vulnerability
|
||||
# mitigation.
|
||||
# - init-all: supports stack variable initialization.
|
||||
# - zeroregs: supports zeroing used registers on return
|
||||
# - aarch64-sha512: supports the AArch64 sha512 intrinsic functions.
|
||||
#
|
||||
# When bootstrapping on macOS, 'apple-clang' will be set in COMPILER_FEATURES
|
||||
|
|
@ -263,6 +264,11 @@ ${X_}COMPILER_FEATURES+= compressed-debug
|
|||
${X_}COMPILER_FEATURES+= fileprefixmap
|
||||
.endif
|
||||
|
||||
.if (${${X_}COMPILER_TYPE} == "clang" && ${${X_}COMPILER_VERSION} >= 150000) || \
|
||||
(${${X_}COMPILER_TYPE} == "gcc" && ${${X_}COMPILER_VERSION} >= 110000)
|
||||
${X_}COMPILER_FEATURES+= zeroregs
|
||||
.endif
|
||||
|
||||
.if (${${X_}COMPILER_TYPE} == "clang" && ${${X_}COMPILER_VERSION} >= 130000) || \
|
||||
(${${X_}COMPILER_TYPE} == "gcc" && ${${X_}COMPILER_VERSION} >= 90000)
|
||||
# AArch64 sha512 intrinsics are supported (and have been tested) in
|
||||
|
|
|
|||
|
|
@ -118,6 +118,15 @@ CXXFLAGS+= -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-cl
|
|||
.endif
|
||||
.endif
|
||||
|
||||
# Zero used registers on return (mitigate some ROP)
|
||||
.if ${MK_ZEROREGS} != "no"
|
||||
.if ${COMPILER_FEATURES:Mzeroregs}
|
||||
ZEROREG_TYPE?= used
|
||||
CFLAGS+= -fzero-call-used-regs=${ZEROREG_TYPE}
|
||||
CXXFLAGS+= -fzero-call-used-regs=${ZEROREG_TYPE}
|
||||
.endif
|
||||
.endif
|
||||
|
||||
# bsd.sanitizer.mk is not installed, so don't require it (e.g. for ports).
|
||||
.sinclude "bsd.sanitizer.mk"
|
||||
|
||||
|
|
|
|||
|
|
@ -81,7 +81,8 @@ __DEFAULT_NO_OPTIONS = \
|
|||
RETPOLINE \
|
||||
STALE_STAGED \
|
||||
UBSAN \
|
||||
UNDEFINED_VERSION
|
||||
UNDEFINED_VERSION \
|
||||
ZEROREGS
|
||||
|
||||
__DEFAULT_DEPENDENT_OPTIONS = \
|
||||
MAKE_CHECK_USE_SANDBOX/TESTS \
|
||||
|
|
|
|||
|
|
@ -90,6 +90,15 @@ CXXFLAGS+= -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-cl
|
|||
.endif
|
||||
.endif
|
||||
|
||||
# Zero used registers on return (mitigate some ROP)
|
||||
.if ${MK_ZEROREGS} != "no"
|
||||
.if ${COMPILER_FEATURES:Mzeroregs}
|
||||
ZEROREG_TYPE?= used
|
||||
CFLAGS+= -fzero-call-used-regs=${ZEROREG_TYPE}
|
||||
CXXFLAGS+= -fzero-call-used-regs=${ZEROREG_TYPE}
|
||||
.endif
|
||||
.endif
|
||||
|
||||
# bsd.sanitizer.mk is not installed, so don't require it (e.g. for ports).
|
||||
.sinclude "bsd.sanitizer.mk"
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ FORTIFY_SOURCE= 0
|
|||
MK_CTF= no
|
||||
MK_SSP= no
|
||||
MK_PIE= no
|
||||
MK_ZEROREGS= no
|
||||
MAN=
|
||||
.if !defined(PIC)
|
||||
NO_PIC=
|
||||
|
|
|
|||
2
tools/build/options/WITHOUT_ZEROREGS
Normal file
2
tools/build/options/WITHOUT_ZEROREGS
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Do not build build the basesystem with code to zero caller-used register
|
||||
contents on function return.
|
||||
4
tools/build/options/WITH_ZEROREGS
Normal file
4
tools/build/options/WITH_ZEROREGS
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
Build the basesystem with code to zero caller-used register contents
|
||||
on function return.
|
||||
This prevents leaking temporary values for side channel attacks.
|
||||
Additionally this reduces the number of usable ROP gadgets for attackers.
|
||||
Loading…
Reference in a new issue