From 35113cde77e4085d1a0c1fbb6361c300c74cb928 Mon Sep 17 00:00:00 2001 From: Giuliano Belinassi Date: Thu, 6 Jun 2024 18:01:57 -0300 Subject: [PATCH 1/2] Check generated code for IBT compatibilty Some kernel versions do not support IBT. Check if we have such cases and emit a runtime error if found. Signed-off-by: Giuliano Belinassi --- libcextract/Passes.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libcextract/Passes.cpp b/libcextract/Passes.cpp index f1b6c34..841b9d3 100644 --- a/libcextract/Passes.cpp +++ b/libcextract/Passes.cpp @@ -460,6 +460,16 @@ class FunctionExternalizerPass : public Pass ClangCompat_None, ctx->OFS); PrettyPrint::Set_Source_Manager(&ctx->AST->getSourceManager()); + if (ctx->Ibt && ctx->AST) { + /* Do a sanity check on IBT macros. Some kernel branches can't use it, + so do a check here for sanity reasons. */ + Preprocessor &pp = ctx->AST->getPreprocessor(); + if (pp.isMacroDefined("KLP_RELOC_SYMBOL") == false) { + throw std::runtime_error("KLP_RELOC_SYMBOL not defined, kernel may not " + "be compatible with IBT."); + } + } + const DiagnosticsEngine &de = ctx->AST->getDiagnostics(); return !de.hasErrorOccurred(); } From 3dca9b752c8c53d990de1a933c9b3b50125753e8 Mon Sep 17 00:00:00 2001 From: Giuliano Belinassi Date: Fri, 7 Jun 2024 10:29:56 -0300 Subject: [PATCH 2/2] Delay output of #include It is possible that we need to emit the #include even before the main file, for example if the header is passed through -include header.h. Signed-off-by: Giuliano Belinassi --- libcextract/SymbolExternalizer.cpp | 18 +++++++++++------- libcextract/SymbolExternalizer.hh | 4 ++++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/libcextract/SymbolExternalizer.cpp b/libcextract/SymbolExternalizer.cpp index a10834a..865f291 100644 --- a/libcextract/SymbolExternalizer.cpp +++ b/libcextract/SymbolExternalizer.cpp @@ -820,6 +820,17 @@ bool SymbolExternalizer::_Externalize_Symbol(const std::string &to_externalize, /* Create a string with the new variable type and name. */ std::string o; llvm::raw_string_ostream outstr(o); + + if (Ibt && !EmittedLinuxLivepatch) { + outstr << "#ifndef KLP_RELOC_SYMBOL_POS\n" + "# define KLP_RELOC_SYMBOL_POS(LP_OBJ_NAME, SYM_OBJ_NAME, SYM_NAME, SYM_POS) \\\n" + " asm(\"\\\".klp.sym.rela.\" #LP_OBJ_NAME \".\" #SYM_OBJ_NAME \".\" #SYM_NAME \",\" #SYM_POS \"\\\"\")\n" + "# define KLP_RELOC_SYMBOL(LP_OBJ_NAME, SYM_OBJ_NAME, SYM_NAME) \\\n" + " KLP_RELOC_SYMBOL_POS(LP_OBJ_NAME, SYM_OBJ_NAME, SYM_NAME, 0)\n" + "#endif\n\n"; + EmittedLinuxLivepatch = true; + } + new_decl->print(outstr, AST->getLangOpts()); if (Ibt) { @@ -961,13 +972,6 @@ void SymbolExternalizer::Externalize_Symbol(const std::string &to_externalize) void SymbolExternalizer::Externalize_Symbols(std::vector const &to_externalize_array) { - if (Ibt) { - SourceManager &sm = AST->getSourceManager(); - FileID fi = sm.getMainFileID(); - SourceLocation sl = sm.getLocForStartOfFile(fi); - Insert_Text(sl, "#include \n"); - } - for (const std::string &to_externalize : to_externalize_array) { Externalize_Symbol(to_externalize); } diff --git a/libcextract/SymbolExternalizer.hh b/libcextract/SymbolExternalizer.hh index 0d53cc1..a19183e 100644 --- a/libcextract/SymbolExternalizer.hh +++ b/libcextract/SymbolExternalizer.hh @@ -192,6 +192,7 @@ class SymbolExternalizer TM(ast, dump), IA(ia), Ibt(ibt), + EmittedLinuxLivepatch(false), PatchObject(patch_object) { } @@ -295,6 +296,9 @@ class SymbolExternalizer /** Defines the method that a private symbol will be searched. */ bool Ibt; + /** Flag if we already emit the #include */ + bool EmittedLinuxLivepatch; + /* Name of the object that will be patched. */ std::string PatchObject; };