From b1aa91797ec2e745e0c00f489416cec9e23d49c9 Mon Sep 17 00:00:00 2001 From: arvinzzz Date: Thu, 23 Mar 2023 22:06:17 +0800 Subject: [PATCH] feature: backward cfi Signed-off-by: arvinzzz Change-Id: I3504230a278db1d967f8697a4bef65d32f9e2791 --- clang/docs/ClangCommandLineReference.rst | 8 +++-- clang/include/clang/Basic/CodeGenOptions.def | 3 ++ clang/include/clang/Basic/LangOptions.h | 2 +- clang/include/clang/Driver/Options.td | 11 +++++-- clang/lib/CodeGen/CGCall.cpp | 2 ++ clang/lib/CodeGen/CodeGenModule.cpp | 6 ++-- clang/lib/Driver/ToolChains/Clang.cpp | 33 ++++++++++++++++--- clang/lib/Frontend/InitPreprocessor.cpp | 6 ++-- lld/ELF/Writer.cpp | 2 +- llvm/docs/LangRef.rst | 11 +++++++ llvm/include/llvm/Bitcode/LLVMBitCodes.h | 3 +- llvm/include/llvm/CodeGen/StackProtector.h | 3 ++ llvm/include/llvm/IR/Attributes.td | 7 ++-- llvm/include/llvm/IR/Function.h | 2 +- llvm/lib/AsmParser/LLParser.cpp | 7 +++- llvm/lib/AsmParser/LLToken.h | 3 +- llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 8 ++--- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 6 ++-- llvm/lib/CodeGen/LocalStackSlotAllocation.cpp | 3 +- llvm/lib/CodeGen/PrologEpilogInserter.cpp | 3 +- llvm/lib/CodeGen/SafeStack.cpp | 3 +- llvm/lib/CodeGen/StackProtector.cpp | 21 +++++++++--- .../lib/CodeGen/StackProtectorRetLowering.cpp | 2 +- .../CodeGen/TargetLoweringObjectFileImpl.cpp | 4 +++ llvm/lib/IR/Attributes.cpp | 16 ++++++--- llvm/lib/IR/Function.cpp | 3 +- llvm/lib/IR/Verifier.cpp | 3 +- llvm/lib/MC/MCParser/ELFAsmParser.cpp | 5 ++- .../AArch64StackProtectorRetLowering.cpp | 10 ++++-- .../lib/Transforms/IPO/ForceFunctionAttrs.cpp | 3 +- llvm/lib/Transforms/Utils/CodeExtractor.cpp | 3 +- 31 files changed, 155 insertions(+), 47 deletions(-) diff --git a/clang/docs/ClangCommandLineReference.rst b/clang/docs/ClangCommandLineReference.rst index 2a9b3fc03123..8cc1b39722e1 100644 --- a/clang/docs/ClangCommandLineReference.rst +++ b/clang/docs/ClangCommandLineReference.rst @@ -2185,9 +2185,13 @@ Enable stack protectors for all functions Enable stack protectors for some functions vulnerable to stack smashing. Compared to -fstack-protector, this uses a stronger heuristic that includes functions containing arrays of any size (and any type), as well as any calls to alloca or the taking of an address from a local variable -.. option:: -fstack-protector-ret +.. option:: -fstack-protector-ret-strong -Enable stack protectors for all functions with return address check +Enable stack protectors for some functions vulnerable to stack smashing with return address check + +.. option:: -fstack-protector-ret-all + +Enable stack protectors for all functions vulnerable to stack smashing with return address check .. option:: -fstack-size-section, -fno-stack-size-section diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index 9d53b5b923bb..748ac93be372 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -325,6 +325,9 @@ VALUE_CODEGENOPT(SmallDataLimit, 32, 0) /// The lower bound for a buffer to be considered for stack protection. VALUE_CODEGENOPT(SSPBufferSize, 32, 0) +/// The maximum total of cookies used by back-forward cfi for stack protection. +VALUE_CODEGENOPT(SSPRetCookieSize, 32, 1) + /// The kind of generated debug info. ENUM_CODEGENOPT(DebugInfo, codegenoptions::DebugInfoKind, 4, codegenoptions::NoDebugInfo) diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index a16ac81f785d..cdbb49111ebe 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -61,7 +61,7 @@ public: using RoundingMode = llvm::RoundingMode; enum GCMode { NonGC, GCOnly, HybridGC }; - enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq, SSPRet }; + enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq, SSPRetStrong, SSPRetReq }; // Automatic variables live on the stack, and when trivial they're usually // uninitialized because it's undefined behavior to use them without diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index d710897c0f29..a452e29a00f1 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2258,8 +2258,10 @@ defm signed_char : OptOutFFlag<"signed-char", "char is signed", "char is unsigne def fsplit_stack : Flag<["-"], "fsplit-stack">, Group; def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group, HelpText<"Enable stack protectors for all functions">; -def fstack_protector_ret : Flag<["-"], "fstack-protector-ret">, Group, +def fstack_protector_ret_all : Flag<["-"], "fstack-protector-ret-all">, Group, HelpText<"Enable stack protectors for all functions with return address check">; +def fstack_protector_ret_strong : Flag<["-"], "fstack-protector-ret-strong">, Group, + HelpText<"Enable stack protectors for some functions with return address check">; defm stack_clash_protection : BoolFOption<"stack-clash-protection", CodeGenOpts<"StackClashProtector">, DefaultFalse, PosFlag, NegFlag, @@ -5117,13 +5119,16 @@ def static_define : Flag<["-"], "static-define">, HelpText<"Should __STATIC__ be defined">, MarshallingInfoFlag>; def stack_protector : Separate<["-"], "stack-protector">, - HelpText<"Enable stack protectors">, Values<"0,1,2,3,4">, + HelpText<"Enable stack protectors">, Values<"0,1,2,3,4,5">, NormalizedValuesScope<"LangOptions">, - NormalizedValues<["SSPOff", "SSPOn", "SSPStrong", "SSPReq", "SSPRet"]>, + NormalizedValues<["SSPOff", "SSPOn", "SSPStrong", "SSPReq", "SSPRetStrong", "SSPRetReq"]>, MarshallingInfoString, "SSPOff">, AutoNormalizeEnum; def stack_protector_buffer_size : Separate<["-"], "stack-protector-buffer-size">, HelpText<"Lower bound for a buffer to be considered for stack protection">, MarshallingInfoStringInt, "8">; +def stack_protector_ret_cookie_size : Separate<["-"], "stack-protector-ret-cookie-size">, + HelpText<"Lower bound for a buffer to be considered for stack protection">, + MarshallingInfoStringInt, "1">; def fvisibility : Separate<["-"], "fvisibility">, HelpText<"Default type and symbol visibility">, MarshallingInfoVisibility, "DefaultVisibility">; diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index bc7582c67989..e5ccf9174ca8 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1809,6 +1809,8 @@ void CodeGenModule::getDefaultFunctionAttributes(StringRef Name, llvm::toStringRef(CodeGenOpts.SoftFloat)); FuncAttrs.addAttribute("stack-protector-buffer-size", llvm::utostr(CodeGenOpts.SSPBufferSize)); + FuncAttrs.addAttribute("stack-protector-ret-cookie-size", + llvm::utostr(CodeGenOpts.SSPRetCookieSize)); FuncAttrs.addAttribute("no-signed-zeros-fp-math", llvm::toStringRef(LangOpts.NoSignedZero)); diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 0b9932785d85..932f13260b34 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1677,8 +1677,10 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, B.addAttribute(llvm::Attribute::StackProtectStrong); else if (LangOpts.getStackProtector() == LangOptions::SSPReq) B.addAttribute(llvm::Attribute::StackProtectReq); - else if (LangOpts.getStackProtector() == LangOptions::SSPRet) - B.addAttribute(llvm::Attribute::StackProtectRet); + else if (LangOpts.getStackProtector() == LangOptions::SSPRetStrong) + B.addAttribute(llvm::Attribute::StackProtectRetStrong); + else if (LangOpts.getStackProtector() == LangOptions::SSPRetReq) + B.addAttribute(llvm::Attribute::StackProtectRetReq); } if (!D) { diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index d3ec5c5329ae..5478695ac12c 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -3007,7 +3007,8 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC, if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector, options::OPT_fstack_protector_all, - options::OPT_fstack_protector_ret, + options::OPT_fstack_protector_ret_all, + options::OPT_fstack_protector_ret_strong, options::OPT_fstack_protector_strong, options::OPT_fstack_protector)) { if (A->getOption().matches(options::OPT_fstack_protector)) @@ -3015,8 +3016,10 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC, std::max<>(LangOptions::SSPOn, DefaultStackProtectorLevel); else if (A->getOption().matches(options::OPT_fstack_protector_strong)) StackProtectorLevel = LangOptions::SSPStrong; - else if (A->getOption().matches(options::OPT_fstack_protector_ret)) - StackProtectorLevel = LangOptions::SSPRet; + else if (A->getOption().matches(options::OPT_fstack_protector_ret_strong)) + StackProtectorLevel = LangOptions::SSPRetStrong; + else if (A->getOption().matches(options::OPT_fstack_protector_ret_all)) + StackProtectorLevel = LangOptions::SSPRetReq; else if (A->getOption().matches(options::OPT_fstack_protector_all)) StackProtectorLevel = LangOptions::SSPReq; } else { @@ -3028,7 +3031,7 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC, CmdArgs.push_back(Args.MakeArgString(Twine(StackProtectorLevel))); } - // --param ssp-buffer-size= + // --param ssp-buffer-size= & ssp-ret-cookie-size= for (const Arg *A : Args.filtered(options::OPT__param)) { StringRef Str(A->getValue()); if (Str.startswith("ssp-buffer-size=")) { @@ -3039,6 +3042,28 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC, } A->claim(); } + if (Str.startswith("ssp-ret-cookie-size=")) { + unsigned int SSPRetCookieSize = 1; + bool IsSizeInvalid = false; + // Currently only supports AArch64 architecture. + if (!EffectiveTriple.isAArch64() || !EffectiveTriple.isOSBinFormatELF()) { + D.Diag(diag::err_drv_unsupported_opt_for_target) + << Str.take_front(19) << EffectiveTriple.getTriple(); + continue; + } + // The ssp-ret-cookie-size must be greater than 0. + IsSizeInvalid = Str.drop_front(20).getAsInteger(10, SSPRetCookieSize); + if (IsSizeInvalid || (SSPRetCookieSize == 0)) { + D.Diag(diag::err_drv_invalid_int_value) + << Str.take_front(19) << Str.drop_front(20); + continue; + } + if (StackProtectorLevel) { + CmdArgs.push_back("-stack-protector-ret-cookie-size"); + CmdArgs.push_back(Args.MakeArgString(Str.drop_front(20))); + } + A->claim(); + } } // First support "tls" and "global" for X86 target. diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 1b783ac5d152..73daea696643 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -1038,8 +1038,10 @@ static void InitializePredefinedMacros(const TargetInfo &TI, Builder.defineMacro("__SSP_STRONG__", "2"); else if (LangOpts.getStackProtector() == LangOptions::SSPReq) Builder.defineMacro("__SSP_ALL__", "3"); - else if (LangOpts.getStackProtector() == LangOptions::SSPRet) - Builder.defineMacro("__SSP_RET__", "4"); + else if (LangOpts.getStackProtector() == LangOptions::SSPRetStrong) + Builder.defineMacro("__SSP_RET_STRONG__", "4"); + else if (LangOpts.getStackProtector() == LangOptions::SSPRetReq) + Builder.defineMacro("__SSP_RET_ALL__", "5"); if (PPOpts.SetUpStaticAnalyzer) Builder.defineMacro("__clang_analyzer__"); diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 884201c871da..117b0d7702cf 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -2452,7 +2452,7 @@ std::vector Writer::createPhdrs(Partition &part) { if (OutputSection *cmd = findSection(".note.gnu.property", partNo)) addHdr(PT_GNU_PROPERTY, PF_R)->add(cmd); - if (OutputSection *cmd = findSection(".ohos.randomdata", partNo)) + if (OutputSection *cmd = findSection(".ohos.randomdata", partNo)) //.bss.ohos.randomdata addHdr(PT_OHOS_RANDOMDATA, cmd->getPhdrFlags())->add(cmd); // Create one PT_NOTE per a group of contiguous SHT_NOTE sections with the diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index eaabf8a0192a..fab8c5254ce9 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -1909,6 +1909,17 @@ example: ``ssp/sspstrong/sspreq`` attribute. If inlined, the caller will get the ``sspreq`` attribute. +``sspretstrong`` + This attribute indicates that the function should emit a stack smashing + protector and backward cfi protector. This attribute will add backward + cfi protection on the basis of ``sspstrong`` + + +``sspretreq`` + This attribute indicates that the function should *always* emit a stack + smashing protector and backward cfi protector. This overrides the ``ssp`` + and ``sspreq`` function attributes. + ``strictfp`` This attribute indicates that the function was called from a scope that requires strict floating-point semantics. LLVM will not attempt any diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h index 830f1792de58..fc60520f4105 100644 --- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h +++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h @@ -657,7 +657,8 @@ enum AttributeKindCodes { ATTR_KIND_NO_CALLBACK = 71, ATTR_KIND_HOT = 72, ATTR_KIND_NO_PROFILE = 73, - ATTR_KIND_STACK_PROTECT_RET = 74, + ATTR_KIND_STACK_PROTECT_RET_REQ = 74, + ATTR_KIND_STACK_PROTECT_RET_STRONG = 75, }; enum ComdatSelectionKindCodes { diff --git a/llvm/include/llvm/CodeGen/StackProtector.h b/llvm/include/llvm/CodeGen/StackProtector.h index d2b82009658f..51ad9e7fc0d1 100644 --- a/llvm/include/llvm/CodeGen/StackProtector.h +++ b/llvm/include/llvm/CodeGen/StackProtector.h @@ -61,6 +61,9 @@ private: /// protection when -fstack-protection is used. unsigned SSPBufferSize = 0; + /// The total of cookies that -fstack-protector-ret used. + unsigned SSPRetCookieSize = 1; + /// VisitedPHIs - The set of PHI nodes visited when determining /// if a variable's reference has been taken. This set /// is maintained to ensure we don't visit the same PHI node multiple diff --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td index d188980201f2..0657cbf0d905 100644 --- a/llvm/include/llvm/IR/Attributes.td +++ b/llvm/include/llvm/IR/Attributes.td @@ -203,8 +203,11 @@ def Speculatable : EnumAttr<"speculatable">; /// Stack protection. def StackProtect : EnumAttr<"ssp">; -/// Stack protection for return address. -def StackProtectRet : EnumAttr<"sspret">; +/// Stack protection for return address required. +def StackProtectRetReq : EnumAttr<"sspretreq">; + +/// Strong stack protection for return address. +def StackProtectRetStrong : EnumAttr<"sspretstrong">; /// Stack protection required. def StackProtectReq : EnumAttr<"sspreq">; diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h index de6fff21a2ed..fa94a88b697b 100644 --- a/llvm/include/llvm/IR/Function.h +++ b/llvm/include/llvm/IR/Function.h @@ -387,7 +387,7 @@ public: void setGC(std::string Str); void clearGC(); - /// Returns true if the function has ssp, sspstrong, sspret or sspreq fn attrs. + /// Returns true if the function has ssp, sspstrong, sspretstrong, sspretreq or sspreq fn attrs. bool hasStackProtectorFnAttr() const; /// adds the attribute to the list of attributes. diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index f6c7794f371f..fbcb091c0733 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -1383,7 +1383,8 @@ bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B, B.addAttribute(Attribute::ReturnsTwice); break; case lltok::kw_speculatable: B.addAttribute(Attribute::Speculatable); break; case lltok::kw_ssp: B.addAttribute(Attribute::StackProtect); break; - case lltok::kw_sspret: B.addAttribute(Attribute::StackProtectRet); break; + case lltok::kw_sspretreq: B.addAttribute(Attribute::StackProtectRetReq); break; + case lltok::kw_sspretstrong: B.addAttribute(Attribute::StackProtectRetStrong); break; case lltok::kw_sspreq: B.addAttribute(Attribute::StackProtectReq); break; case lltok::kw_sspstrong: B.addAttribute(Attribute::StackProtectStrong); break; @@ -1798,6 +1799,8 @@ bool LLParser::parseOptionalParamAttrs(AttrBuilder &B) { case lltok::kw_ssp: case lltok::kw_sspreq: case lltok::kw_sspstrong: + case lltok::kw_sspretreq: + case lltok::kw_sspretstrong: case lltok::kw_safestack: case lltok::kw_shadowcallstack: case lltok::kw_strictfp: @@ -1907,6 +1910,8 @@ bool LLParser::parseOptionalReturnAttrs(AttrBuilder &B) { case lltok::kw_ssp: case lltok::kw_sspreq: case lltok::kw_sspstrong: + case lltok::kw_sspretreq: + case lltok::kw_sspretstrong: case lltok::kw_safestack: case lltok::kw_shadowcallstack: case lltok::kw_strictfp: diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h index a93cdfff73ca..21d512449d61 100644 --- a/llvm/lib/AsmParser/LLToken.h +++ b/llvm/lib/AsmParser/LLToken.h @@ -228,7 +228,8 @@ enum Kind { kw_signext, kw_speculatable, kw_ssp, - kw_sspret, + kw_sspretreq, + kw_sspretstrong, kw_sspreq, kw_sspstrong, kw_safestack, diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 83a5d44da694..20fc333501a9 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1289,8 +1289,6 @@ static uint64_t getRawAttributeMask(Attribute::AttrKind Val) { return 1ULL << 62; case Attribute::NoFree: return 1ULL << 63; - case Attribute::StackProtectRet: - return 1ULL << 64; default: // Other attributes are not supported in the raw format, // as we ran out of space. @@ -1495,8 +1493,10 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::StackAlignment; case bitc::ATTR_KIND_STACK_PROTECT: return Attribute::StackProtect; - case bitc::ATTR_KIND_STACK_PROTECT_RET: - return Attribute::StackProtectRet; + case bitc::ATTR_KIND_STACK_PROTECT_RET_REQ: + return Attribute::StackProtectRetReq; + case bitc::ATTR_KIND_STACK_PROTECT_RET_STRONG: + return Attribute::StackProtectRetStrong; case bitc::ATTR_KIND_STACK_PROTECT_REQ: return Attribute::StackProtectReq; case bitc::ATTR_KIND_STACK_PROTECT_STRONG: diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 27d2a625086e..1277f5cc923a 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -708,8 +708,10 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) { return bitc::ATTR_KIND_STACK_ALIGNMENT; case Attribute::StackProtect: return bitc::ATTR_KIND_STACK_PROTECT; - case Attribute::StackProtectRet: - return bitc::ATTR_KIND_STACK_PROTECT_RET; + case Attribute::StackProtectRetReq: + return bitc::ATTR_KIND_STACK_PROTECT_RET_REQ; + case Attribute::StackProtectRetStrong: + return bitc::ATTR_KIND_STACK_PROTECT_RET_STRONG; case Attribute::StackProtectReq: return bitc::ATTR_KIND_STACK_PROTECT_REQ; case Attribute::StackProtectStrong: diff --git a/llvm/lib/CodeGen/LocalStackSlotAllocation.cpp b/llvm/lib/CodeGen/LocalStackSlotAllocation.cpp index b005e15f6651..7ef51615e3cd 100644 --- a/llvm/lib/CodeGen/LocalStackSlotAllocation.cpp +++ b/llvm/lib/CodeGen/LocalStackSlotAllocation.cpp @@ -247,7 +247,8 @@ void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) { Offset, MaxAlign); AssignProtectedObjSet(AddrOfObjs, ProtectedObjs, MFI, StackGrowsDown, Offset, MaxAlign); - } else if (F.hasFnAttribute(Attribute::StackProtectRet)) { + } else if (F.hasFnAttribute(Attribute::StackProtectRetReq) || + F.hasFnAttribute(Attribute::StackProtectRetStrong)) { StackObjSet LargeArrayObjs; StackObjSet SmallArrayObjs; StackObjSet AddrOfObjs; diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp index 41e11683e668..ca372b899bdb 100644 --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -1177,7 +1177,8 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &MF) { Offset, MaxAlign, Skew); AssignProtectedObjSet(AddrOfObjs, ProtectedObjs, MFI, StackGrowsDown, Offset, MaxAlign, Skew); - } else if (F.hasFnAttribute(Attribute::StackProtectRet)) { + } else if (F.hasFnAttribute(Attribute::StackProtectRetReq) || + F.hasFnAttribute(Attribute::StackProtectRetStrong)) { StackObjSet LargeArrayObjs; StackObjSet SmallArrayObjs; StackObjSet AddrOfObjs; diff --git a/llvm/lib/CodeGen/SafeStack.cpp b/llvm/lib/CodeGen/SafeStack.cpp index 3f14f68707b7..5c1a0ee602d2 100644 --- a/llvm/lib/CodeGen/SafeStack.cpp +++ b/llvm/lib/CodeGen/SafeStack.cpp @@ -810,7 +810,8 @@ bool SafeStack::run() { if (F.hasFnAttribute(Attribute::StackProtect) || F.hasFnAttribute(Attribute::StackProtectStrong) || F.hasFnAttribute(Attribute::StackProtectReq) || - F.hasFnAttribute(Attribute::StackProtectRet)) { + F.hasFnAttribute(Attribute::StackProtectRetStrong) || + F.hasFnAttribute(Attribute::StackProtectRetReq)) { Value *StackGuard = getStackGuard(IRB, F); StackGuardSlot = IRB.CreateAlloca(StackPtrTy, nullptr); IRB.CreateStore(StackGuard, StackGuardSlot); diff --git a/llvm/lib/CodeGen/StackProtector.cpp b/llvm/lib/CodeGen/StackProtector.cpp index 2f0094fa7369..141df36dfe53 100644 --- a/llvm/lib/CodeGen/StackProtector.cpp +++ b/llvm/lib/CodeGen/StackProtector.cpp @@ -97,6 +97,14 @@ bool StackProtector::runOnFunction(Function &Fn) { Attr.getValueAsString().getAsInteger(10, SSPBufferSize)) return false; // Invalid integer string + Attr = Fn.getFnAttribute("stack-protector-ret-cookie-size"); + if (Attr.isStringAttribute()) { + if (Attr.getValueAsString().getAsInteger(10, SSPRetCookieSize)) + return false; // Invalid integer string + if (!SSPRetCookieSize) + return false; // Invalid integer string + } + if (!RequiresStackProtector()) return false; @@ -110,7 +118,8 @@ bool StackProtector::runOnFunction(Function &Fn) { ++NumFunProtected; - if (Fn.hasFnAttribute(Attribute::StackProtectRet)) { + if (Fn.hasFnAttribute(Attribute::StackProtectRetReq) || + Fn.hasFnAttribute(Attribute::StackProtectRetStrong)) { HasIRCheck = true; CreateSSPRetCookie(); // StackProtectRet requires special code generation methods for backward cfi. @@ -122,11 +131,13 @@ bool StackProtector::runOnFunction(Function &Fn) { bool StackProtector::CreateSSPRetCookie() { - std::string cookiename = "__sspret_cookie"; Type *cookietype = Type::getInt8PtrTy(M->getContext()); + std::hash hasher; + std::string hash = std::to_string(hasher((M->getName() + F->getName()).str()) % SSPRetCookieSize); + std::string cookiename = "__sspret_cookie_" + hash; GlobalVariable *cookie = dyn_cast_or_null(M->getOrInsertGlobal(cookiename, cookietype)); - cookie->setSection(".ohos.randomdata"); + cookie->setSection(".ohos.randomdata");//.ohos.randomdata cookie->setExternallyInitialized(true); cookie->setInitializer(Constant::getNullValue(cookietype)); cookie->setLinkage(GlobalVariable::LinkOnceAnyLinkage); @@ -318,9 +329,11 @@ bool StackProtector::RequiresStackProtector() { }); NeedsProtector = true; Strong = true; // Use the same heuristic as strong to determine SSPLayout - } else if (F->hasFnAttribute(Attribute::StackProtectRet)) { + } else if (F->hasFnAttribute(Attribute::StackProtectRetReq)) { NeedsProtector = true; Strong = true; + } else if (F->hasFnAttribute(Attribute::StackProtectRetStrong)) { + Strong = true; } else if (F->hasFnAttribute(Attribute::StackProtectStrong)) Strong = true; else if (!F->hasFnAttribute(Attribute::StackProtect)) diff --git a/llvm/lib/CodeGen/StackProtectorRetLowering.cpp b/llvm/lib/CodeGen/StackProtectorRetLowering.cpp index 4b068995c743..d367cf797dde 100644 --- a/llvm/lib/CodeGen/StackProtectorRetLowering.cpp +++ b/llvm/lib/CodeGen/StackProtectorRetLowering.cpp @@ -23,7 +23,7 @@ using namespace llvm; /// Check if backward CFI protection is required. void StackProtectorRetLowering::setupStackProtectorRet(MachineFunction &MF) const { - if (MF.getFunction().hasFnAttribute(Attribute::StackProtectRet)) { + if (MF.getFunction().hasFnAttribute("sspret-randomdata")) { for (auto &MBB : MF) { for (auto &T : MBB.terminators()) { if (instrIsRet(T.getOpcode())) { diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index fe64b38cf0be..a9b7049fa6cb 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -484,6 +484,10 @@ static unsigned getELFSectionType(StringRef Name, SectionKind K) { if (Name == ".preinit_array") return ELF::SHT_PREINIT_ARRAY; + // ohos customized section, does not occupy ROM in ELF. + if (Name == ".ohos.randomdata") + return ELF::SHT_NOBITS; + if (K.isBSS() || K.isThreadBSS()) return ELF::SHT_NOBITS; diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index e0f1cc217d58..1b08b2f36341 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -431,8 +431,10 @@ std::string Attribute::getAsString(bool InAttrGrp) const { return "speculatable"; if (hasAttribute(Attribute::StackProtect)) return "ssp"; - if (hasAttribute(Attribute::StackProtectRet)) - return "sspret"; + if (hasAttribute(Attribute::StackProtectRetReq)) + return "sspretreq"; + if (hasAttribute(Attribute::StackProtectRetStrong)) + return "sspretstrong"; if (hasAttribute(Attribute::StackProtectReq)) return "sspreq"; if (hasAttribute(Attribute::StackProtectStrong)) @@ -1968,18 +1970,22 @@ static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) { AttrBuilder OldSSPAttr; OldSSPAttr.addAttribute(Attribute::StackProtect) .addAttribute(Attribute::StackProtectStrong) + .addAttribute(Attribute::StackProtectRetStrong) .addAttribute(Attribute::StackProtectReq) - .addAttribute(Attribute::StackProtectRet); + .addAttribute(Attribute::StackProtectRetReq); - if (Callee.hasFnAttribute(Attribute::StackProtectRet) && + if (Callee.hasFnAttribute(Attribute::StackProtectRetReq) && !Caller.hasFnAttribute(Attribute::StackProtect) && !Caller.hasFnAttribute(Attribute::StackProtectReq) && !Caller.hasFnAttribute(Attribute::StackProtectStrong)) { Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr); - Caller.addFnAttr(Attribute::StackProtectRet); + Caller.addFnAttr(Attribute::StackProtectRetReq); } else if (Callee.hasFnAttribute(Attribute::StackProtectReq)) { Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr); Caller.addFnAttr(Attribute::StackProtectReq); + } else if (Callee.hasFnAttribute(Attribute::StackProtectRetStrong)) { + Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr); + Caller.addFnAttr(Attribute::StackProtectRetStrong); } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) && !Caller.hasFnAttribute(Attribute::StackProtectReq)) { Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr); diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index d6862c2dcc6e..278388457711 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -616,7 +616,8 @@ bool Function::hasStackProtectorFnAttr() const { return hasFnAttribute(Attribute::StackProtect) || hasFnAttribute(Attribute::StackProtectStrong) || hasFnAttribute(Attribute::StackProtectReq) || - hasFnAttribute(Attribute::StackProtectRet); + hasFnAttribute(Attribute::StackProtectRetStrong) || + hasFnAttribute(Attribute::StackProtectRetReq); } /// Copy all additional attributes (those not needed to create a Function) from diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 7d70eed0c91d..788ac3d4bc8d 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -1612,7 +1612,8 @@ static bool isFuncOnlyAttr(Attribute::AttrKind Kind) { case Attribute::AlwaysInline: case Attribute::OptimizeForSize: case Attribute::StackProtect: - case Attribute::StackProtectRet: + case Attribute::StackProtectRetReq: + case Attribute::StackProtectRetStrong: case Attribute::StackProtectReq: case Attribute::StackProtectStrong: case Attribute::SafeStack: diff --git a/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/llvm/lib/MC/MCParser/ELFAsmParser.cpp index 65ac1d6b5ba0..40cef16adf5d 100644 --- a/llvm/lib/MC/MCParser/ELFAsmParser.cpp +++ b/llvm/lib/MC/MCParser/ELFAsmParser.cpp @@ -515,7 +515,8 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) { hasPrefix(SectionName, ".bss.") || hasPrefix(SectionName, ".init_array.") || hasPrefix(SectionName, ".fini_array.") || - hasPrefix(SectionName, ".preinit_array.")) + hasPrefix(SectionName, ".preinit_array.") || + hasPrefix(SectionName, ".ohos.randomdata.") || SectionName == ".ohos.randomdata") Flags |= ELF::SHF_ALLOC | ELF::SHF_WRITE; else if (hasPrefix(SectionName, ".tdata.") || hasPrefix(SectionName, ".tbss.")) @@ -601,6 +602,8 @@ EndStmt: Type = ELF::SHT_FINI_ARRAY; else if (hasPrefix(SectionName, ".preinit_array.")) Type = ELF::SHT_PREINIT_ARRAY; + else if (hasPrefix(SectionName, ".ohos.randomdata")) + Type = ELF::SHT_NOBITS; } else { if (TypeName == "init_array") Type = ELF::SHT_INIT_ARRAY; diff --git a/llvm/lib/Target/AArch64/AArch64StackProtectorRetLowering.cpp b/llvm/lib/Target/AArch64/AArch64StackProtectorRetLowering.cpp index c5f67968a212..204b8590c831 100644 --- a/llvm/lib/Target/AArch64/AArch64StackProtectorRetLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64StackProtectorRetLowering.cpp @@ -37,7 +37,10 @@ void AArch64StackProtectorRetLowering::insertStackProtectorRetPrologue( BuildMI(MBB, MI, MBBDL, TII->get(AArch64::LDRXui), REG) .addReg(REG) .addGlobalAddress(cookie, 0, AArch64II::MO_PAGEOFF | AArch64II::MO_NC); - BuildMI(MBB, MI, MBBDL, TII->get(AArch64::ANDXrr), REG) + BuildMI(MBB, MI, MBBDL, TII->get(AArch64::EORXrr), REG) + .addReg(REG) + .addReg(AArch64::FP); + BuildMI(MBB, MI, MBBDL, TII->get(AArch64::EORXrr), REG) .addReg(REG) .addReg(AArch64::LR); } @@ -56,7 +59,10 @@ void AArch64StackProtectorRetLowering::insertStackProtectorRetEpilogue( BuildMI(MBB, MI, MBBDL, TII->get(AArch64::LDRXui), AArch64::X9) .addReg(AArch64::X9) .addGlobalAddress(cookie, 0, AArch64II::MO_PAGEOFF | AArch64II::MO_NC); - BuildMI(MBB, MI, MBBDL, TII->get(AArch64::ANDXrr), AArch64::X9) + BuildMI(MBB, MI, MBBDL, TII->get(AArch64::EORXrr), AArch64::X9) + .addReg(AArch64::X9) + .addReg(AArch64::FP); + BuildMI(MBB, MI, MBBDL, TII->get(AArch64::EORXrr), AArch64::X9) .addReg(AArch64::X9) .addReg(AArch64::LR); BuildMI(MBB, MI, MBBDL, TII->get(AArch64::SUBSXrr), REG) diff --git a/llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp b/llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp index fc8479496ffd..728f3a6fbcb9 100644 --- a/llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp +++ b/llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp @@ -69,7 +69,8 @@ static Attribute::AttrKind parseAttrKind(StringRef Kind) { .Case("sanitize_memtag", Attribute::SanitizeMemTag) .Case("speculative_load_hardening", Attribute::SpeculativeLoadHardening) .Case("ssp", Attribute::StackProtect) - .Case("sspret", Attribute::StackProtectRet) + .Case("sspretreq", Attribute::StackProtectRetReq) + .Case("sspretstrong", Attribute::StackProtectRetStrong) .Case("sspreq", Attribute::StackProtectReq) .Case("sspstrong", Attribute::StackProtectStrong) .Case("strictfp", Attribute::StrictFP) diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp index cccf36ae9831..0e8d6816a30e 100644 --- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp +++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp @@ -967,7 +967,8 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs, case Attribute::SanitizeMemTag: case Attribute::SpeculativeLoadHardening: case Attribute::StackProtect: - case Attribute::StackProtectRet: + case Attribute::StackProtectRetReq: + case Attribute::StackProtectRetStrong: case Attribute::StackProtectReq: case Attribute::StackProtectStrong: case Attribute::StrictFP: -- Gitee