diff --git a/clang/docs/ClangCommandLineReference.rst b/clang/docs/ClangCommandLineReference.rst index 2a9b3fc031231eb4591cfb7cd5f0d84df743a7c9..8cc1b39722e1b071315e1d734bada58adb8830a7 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 9d53b5b923bb2641c212acb688ab452b5de5a3f0..748ac93be372b6217b83d7dbf7d84a06028a267c 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 a16ac81f785d53b2a1dd41e80190d28e389782c4..cdbb49111ebe1ba6645c3ccd68f9ad82a644de56 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 d710897c0f29fbc77db557d29f13ff41346f59a4..a452e29a00f1d68d2dfe02e604148a66d7014ae6 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 bc7582c679894a0591d6d0b6937fddf5e0a4dcba..e5ccf9174ca8771bc942b5f5e33f320a3a316a25 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 0b9932785d856814cac35eb419b55f8b22499835..932f13260b34363d05af9ceafc9550c9b819ea84 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 d3ec5c5329aea6b972893680e8c912cb5da265d9..5478695ac12ca0eea0455502f5f4a5c6a902a29d 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 1b783ac5d152c755f3954d7850e58aa8bd20dee8..73daea6966430fb72e97a67632dc8f5aae9c13bb 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 884201c871da31a8b99c5ad418b8bf77200028e9..117b0d7702cf8696aabed6d107c61b234a00ac19 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 eaabf8a0192a5094a5a191e6fa01ba66cd83e3fc..fab8c5254ce90b29be1507bcfb65b3c2f95db96c 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 830f1792de58a23baa166a6541a9770f8ebfa83a..fc60520f41054253a2fcbc8f529dd70adec25917 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 d2b82009658ff09d98af436f632a1b673f20ec27..51ad9e7fc0d1d8547e895483f739bd9e1f843663 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 d188980201f274e7f7ed3e39e274e6251e20b0f3..0657cbf0d905a54dd633087173860765bb0cece1 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 de6fff21a2ed52eb61ffb86ab0d0f98cdbb7e891..fa94a88b697b79ed5a21ee37d76b82f01951ebd1 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 f6c7794f371ff52770f1a93edb3d057d92685fa5..fbcb091c07337d2c4510c74aa365d60fa20d3823 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 a93cdfff73ca550c2fefffabfa2d0aa7d16366b8..21d512449d61913a67547204625a1f771dff3d1e 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 83a5d44da6948e49860fef1359f9df79711e5a72..20fc333501a9ede14376f340e43bea42ec7d1346 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 27d2a625086ea3f845ac87d97553e954584b16bc..1277f5cc923a647faa1a3c642a1589d6838ae726 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 b005e15f6651fa6a5ef142856654596803cd235b..7ef51615e3cda59e54bbc62d959f8dc44b7336c9 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 41e11683e6688426c3e052401ad7e8a03f377808..ca372b899bdb2e2bb46a307839be4124a85c5338 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 3f14f68707b7c41d22ec16cfb1a76c0412850bac..5c1a0ee602d2ade1f58cde98ce1f3c8c55524a56 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 2f0094fa7369df228f1057f4c02996699be96d35..141df36dfe53bd5c18a102c60b0e1222772ae9fd 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 4b068995c7437b5b08314c5be60536749a6ffc8d..d367cf797dde568fff8224e8b2f9c0af62a0400c 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 fe64b38cf0be215c28639ac81b08eb1eb5dd9eb8..a9b7049fa6cbe8672b83f613d59e707b60805cd4 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 e0f1cc217d58c8810e48d8a52d8229558074c821..1b08b2f3634150e18cb8ce7cbec2c8774d7781bd 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 d6862c2dcc6e00e3a482cc7f8fbce06279671ca5..27838845771107249464ddaad5695a66d3b45d26 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 7d70eed0c91dedbbcc06139b7cdd8b797df4e25e..788ac3d4bc8d99eb0b236886f7293b4c4138af33 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 65ac1d6b5ba0954a5142c45c5316cff545b525e1..40cef16adf5d888b7a17c7971516ca99b7f5fb1f 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 c5f67968a2121d9857936748983c6a948b1b4393..204b8590c8311e7a3b14649edeb62dd438653a95 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 fc8479496ffd95714bfcd75c0435248302ef4fde..728f3a6fbcb90790570f0105f5c1b9ac396f8230 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 cccf36ae9831dd98766d6a9300be8a7efc541688..0e8d6816a30ec6c458cec92be24901521b53c63e 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: