From 3f0587d0c668202bb89d29a25432aa290e551a31 Mon Sep 17 00:00:00 2001 From: Connor Kuehl Date: Fri, 8 Apr 2022 12:47:11 -0700 Subject: [randstruct] Add randomize structure layout support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Randstruct feature is a compile-time hardening technique that randomizes the field layout for designated structures of a code base. Admittedly, this is mostly useful for closed-source releases of code, since the randomization seed would need to be available for public and open source applications. Why implement it? This patch set enhances Clang’s feature parity with that of GCC which already has the Randstruct feature. It's used by the Linux kernel in certain structures to help thwart attacks that depend on structure layouts in memory. This patch set is a from-scratch reimplementation of the Randstruct feature that was originally ported to GCC. The patches for the GCC implementation can be found here: https://www.openwall.com/lists/kernel-hardening/2017/04/06/14 Link: https://lists.llvm.org/pipermail/cfe-dev/2019-March/061607.html Co-authored-by: Cole Nixon Co-authored-by: Connor Kuehl Co-authored-by: James Foster Co-authored-by: Jeff Takahashi Co-authored-by: Jordan Cantrell Co-authored-by: Nikk Forbus Co-authored-by: Tim Pugh Co-authored-by: Bill Wendling Signed-off-by: Bill Wendling Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D121556 --- clang/lib/Frontend/CompilerInvocation.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'clang/lib/Frontend/CompilerInvocation.cpp') diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 83de27b..5181999 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -94,6 +94,7 @@ #include #include #include +#include #include #include #include @@ -3685,6 +3686,9 @@ void CompilerInvocation::GenerateLangArgs(const LangOptions &Opts, for (const auto &MP : Opts.MacroPrefixMap) GenerateArg(Args, OPT_fmacro_prefix_map_EQ, MP.first + "=" + MP.second, SA); + + if (!Opts.RandstructSeed.empty()) + GenerateArg(Args, OPT_frandomize_layout_seed_EQ, Opts.RandstructSeed, SA); } bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, @@ -4237,6 +4241,19 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, Diags.Report(diag::err_cc1_unbounded_vscale_min); } + if (const Arg *A = Args.getLastArg(OPT_frandomize_layout_seed_file_EQ)) { + std::ifstream SeedFile(A->getValue(0)); + + if (!SeedFile.is_open()) + Diags.Report(diag::err_drv_cannot_open_randomize_layout_seed_file) + << A->getValue(0); + + std::getline(SeedFile, Opts.RandstructSeed); + } + + if (const Arg *A = Args.getLastArg(OPT_frandomize_layout_seed_EQ)) + Opts.RandstructSeed = A->getValue(0); + return Diags.getNumErrors() == NumErrorsBefore; } -- cgit v1.1