From 896063e4d924bef6229f6695f274b5282f1e3d23 Mon Sep 17 00:00:00 2001 From: deraadt Date: Sun, 2 Jun 2024 15:40:38 +0000 Subject: [PATCH] add -fret-clean option (amd64 and i386 only at first), defaulting to off. This causes the caller to cleans the return address off the stack after a callq completes. The option is best used in low-level libraries (such as libc), because libc contains low-level system call stubs. The option reduces hints (found on the stale parts of the stack) about libc.so's mapping location, and together with random-relinking, relro got/pic, and xonly makes some exploit methods more difficult. ok mortimer, mlarkin, much discussion with kettenis, in snaps for 2 weeks. --- gnu/llvm/clang/include/clang/Driver/Options.td | 4 ++++ gnu/llvm/clang/lib/Driver/ToolChains/Clang.cpp | 10 ++++++++++ gnu/llvm/llvm/lib/Target/X86/X86.h | 4 ++++ gnu/llvm/llvm/lib/Target/X86/X86TargetMachine.cpp | 2 ++ gnu/usr.bin/clang/libLLVMX86CodeGen/Makefile | 3 ++- share/man/man1/clang-local.1 | 11 +++++++++-- 6 files changed, 31 insertions(+), 3 deletions(-) diff --git a/gnu/llvm/clang/include/clang/Driver/Options.td b/gnu/llvm/clang/include/clang/Driver/Options.td index 7a299510905..a5df86eba14 100644 --- a/gnu/llvm/clang/include/clang/Driver/Options.td +++ b/gnu/llvm/clang/include/clang/Driver/Options.td @@ -2857,6 +2857,10 @@ def fno_fixup_gadgets : Flag<["-"], "fno-fixup-gadgets">, Group, Flags< HelpText<"Disable FixupGadgets pass (x86 only)">; def ffixup_gadgets : Flag<["-"], "ffixup-gadgets">, Group, Flags<[CoreOption]>, HelpText<"Replace ROP friendly instructions with safe alternatives (x86 only)">; +def fno_ret_clean : Flag<["-"], "fno-ret-clean">, Group, Flags<[CoreOption]>, + HelpText<"Disable ret-clean pass">; +def fret_clean : Flag<["-"], "fret-clean">, Group, Flags<[CoreOption]>, + HelpText<"Clean return address from stack after call">; def ftrivial_auto_var_init_stop_after : Joined<["-"], "ftrivial-auto-var-init-stop-after=">, Group, Flags<[CC1Option, CoreOption]>, HelpText<"Stop initializing trivial automatic stack variables after the specified number of instances">, MarshallingInfoInt>; diff --git a/gnu/llvm/clang/lib/Driver/ToolChains/Clang.cpp b/gnu/llvm/clang/lib/Driver/ToolChains/Clang.cpp index 1d073428fe5..6eaa9918302 100644 --- a/gnu/llvm/clang/lib/Driver/ToolChains/Clang.cpp +++ b/gnu/llvm/clang/lib/Driver/ToolChains/Clang.cpp @@ -6402,6 +6402,16 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString(Twine("-x86-fixup-gadgets=true"))); } + // -ret-clean + if (Arg *A = Args.getLastArg(options::OPT_fno_ret_clean, + options::OPT_fret_clean)) { + CmdArgs.push_back(Args.MakeArgString(Twine("-mllvm"))); + if (A->getOption().matches(options::OPT_fno_ret_clean)) + CmdArgs.push_back(Args.MakeArgString(Twine("-x86-ret-clean=false"))); + else if (A->getOption().matches(options::OPT_fret_clean)) + CmdArgs.push_back(Args.MakeArgString(Twine("-x86-ret-clean=true"))); + } + RenderSCPOptions(TC, Args, CmdArgs); RenderTrivialAutoVarInitOptions(D, TC, Args, CmdArgs); diff --git a/gnu/llvm/llvm/lib/Target/X86/X86.h b/gnu/llvm/llvm/lib/Target/X86/X86.h index 3d0eef8d8ac..bf4503dd65b 100644 --- a/gnu/llvm/llvm/lib/Target/X86/X86.h +++ b/gnu/llvm/llvm/lib/Target/X86/X86.h @@ -132,6 +132,10 @@ FunctionPass *createX86DomainReassignmentPass(); /// ROP friendly instructions with alternatives. FunctionPass *createX86FixupGadgetsPass(); +/// Return a Machine Function pass that attempts to replace +/// RET instructions with a cleaning sequence +FunctionPass *createX86RetCleanPass(); + /// This pass replaces EVEX encoded of AVX-512 instructiosn by VEX /// encoding when possible in order to reduce code size. FunctionPass *createX86EvexToVexInsts(); diff --git a/gnu/llvm/llvm/lib/Target/X86/X86TargetMachine.cpp b/gnu/llvm/llvm/lib/Target/X86/X86TargetMachine.cpp index 306a53e94fd..5d4b1b9d010 100644 --- a/gnu/llvm/llvm/lib/Target/X86/X86TargetMachine.cpp +++ b/gnu/llvm/llvm/lib/Target/X86/X86TargetMachine.cpp @@ -596,6 +596,8 @@ void X86PassConfig::addPreEmitPass2() { addPass(createX86IndirectThunksPass()); addPass(createX86ReturnThunksPass()); + addPass(createX86RetCleanPass()); + // Insert extra int3 instructions after trailing call instructions to avoid // issues in the unwinder. if (TT.isOSWindows() && TT.getArch() == Triple::x86_64) diff --git a/gnu/usr.bin/clang/libLLVMX86CodeGen/Makefile b/gnu/usr.bin/clang/libLLVMX86CodeGen/Makefile index 0dd32c5c2cd..143e37b4346 100644 --- a/gnu/usr.bin/clang/libLLVMX86CodeGen/Makefile +++ b/gnu/usr.bin/clang/libLLVMX86CodeGen/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.18 2023/11/11 18:35:38 robert Exp $ +# $OpenBSD: Makefile,v 1.19 2024/06/02 15:40:42 deraadt Exp $ LIB= LLVMX86CodeGen NOPROFILE= @@ -25,6 +25,7 @@ SRCS+= X86AsmPrinter.cpp \ X86FastISel.cpp \ X86FixupBWInsts.cpp \ X86FixupGadgets.cpp \ + X86RetClean.cpp \ X86FixupLEAs.cpp \ X86AvoidStoreForwardingBlocks.cpp \ X86DynAllocaExpander.cpp \ diff --git a/share/man/man1/clang-local.1 b/share/man/man1/clang-local.1 index 9e02e6972a1..6cc7e0d6b7d 100644 --- a/share/man/man1/clang-local.1 +++ b/share/man/man1/clang-local.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: clang-local.1,v 1.23 2022/02/18 00:39:18 jca Exp $ +.\" $OpenBSD: clang-local.1,v 1.24 2024/06/02 15:40:43 deraadt Exp $ .\" .\" Copyright (c) 2016 Pascal Stumpf .\" @@ -15,7 +15,7 @@ .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" .\" -.Dd $Mdocdate: February 18 2022 $ +.Dd $Mdocdate: June 2 2024 $ .Dt CLANG-LOCAL 1 .Os .Sh NAME @@ -119,6 +119,13 @@ This can be disabled with the option. .It .Nm clang +includes a security pass that can clear the return address on the +stack upon return from calling a function, on i386 and amd64. +This can be enabled with the +.Fl fret-clean +option. +.It +.Nm clang includes the retguard security feature on amd64, arm64, mips64, powerpc and powerpc64. This feature can be disabled with the -- 2.20.1