Backport patch to fix CVE-2024-31852
reference:b1a5ee1feband749384c08eSigned-off-by: liyunfei <liyunfei33@huawei.com>
This commit is contained in:
parent
1ec20fc5b1
commit
332fb03bb7
@ -0,0 +1,87 @@
|
|||||||
|
From 4aec2da60ce3f639e31d81406c09d5c88b3b8f53 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florian Hahn <flo@fhahn.com>
|
||||||
|
Date: Wed, 20 Dec 2023 16:56:15 +0100
|
||||||
|
Subject: [PATCH 2/3] [ARM] Check all terms in emitPopInst when clearing
|
||||||
|
Restored for LR. (#75527)
|
||||||
|
|
||||||
|
emitPopInst checks a single function exit MBB. If other paths also exit
|
||||||
|
the function and any of there terminators uses LR implicitly, it is not
|
||||||
|
save to clear the Restored bit.
|
||||||
|
|
||||||
|
Check all terminators for the function before clearing Restored.
|
||||||
|
|
||||||
|
This fixes a mis-compile in outlined-fn-may-clobber-lr-in-caller.ll
|
||||||
|
where the machine-outliner previously introduced BLs that clobbered LR
|
||||||
|
which in turn is used by the tail call return.
|
||||||
|
|
||||||
|
Alternative to #73553
|
||||||
|
---
|
||||||
|
llvm/lib/Target/ARM/ARMFrameLowering.cpp | 30 +++++++++++++++++++++---
|
||||||
|
llvm/lib/Target/ARM/ARMFrameLowering.h | 3 +++
|
||||||
|
2 files changed, 30 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
|
||||||
|
index 4496d4928ebe..650f4650eef0 100644
|
||||||
|
--- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp
|
||||||
|
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
|
||||||
|
@@ -1645,9 +1645,6 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
|
||||||
|
// Fold the return instruction into the LDM.
|
||||||
|
DeleteRet = true;
|
||||||
|
LdmOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_RET : ARM::LDMIA_RET;
|
||||||
|
- // We 'restore' LR into PC so it is not live out of the return block:
|
||||||
|
- // Clear Restored bit.
|
||||||
|
- Info.setRestored(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If NoGap is true, pop consecutive registers and then leave the rest
|
||||||
|
@@ -2769,6 +2766,33 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
|
||||||
|
AFI->setLRIsSpilled(SavedRegs.test(ARM::LR));
|
||||||
|
}
|
||||||
|
|
||||||
|
+void ARMFrameLowering::processFunctionBeforeFrameFinalized(
|
||||||
|
+ MachineFunction &MF, RegScavenger *RS) const {
|
||||||
|
+ TargetFrameLowering::processFunctionBeforeFrameFinalized(MF, RS);
|
||||||
|
+
|
||||||
|
+ MachineFrameInfo &MFI = MF.getFrameInfo();
|
||||||
|
+ if (!MFI.isCalleeSavedInfoValid())
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ // Check if all terminators do not implicitly use LR. Then we can 'restore' LR
|
||||||
|
+ // into PC so it is not live out of the return block: Clear the Restored bit
|
||||||
|
+ // in that case.
|
||||||
|
+ for (CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) {
|
||||||
|
+ if (Info.getReg() != ARM::LR)
|
||||||
|
+ continue;
|
||||||
|
+ if (all_of(MF, [](const MachineBasicBlock &MBB) {
|
||||||
|
+ return all_of(MBB.terminators(), [](const MachineInstr &Term) {
|
||||||
|
+ return !Term.isReturn() || Term.getOpcode() == ARM::LDMIA_RET ||
|
||||||
|
+ Term.getOpcode() == ARM::t2LDMIA_RET ||
|
||||||
|
+ Term.getOpcode() == ARM::tPOP_RET;
|
||||||
|
+ });
|
||||||
|
+ })) {
|
||||||
|
+ Info.setRestored(false);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void ARMFrameLowering::getCalleeSaves(const MachineFunction &MF,
|
||||||
|
BitVector &SavedRegs) const {
|
||||||
|
TargetFrameLowering::getCalleeSaves(MF, SavedRegs);
|
||||||
|
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.h b/llvm/lib/Target/ARM/ARMFrameLowering.h
|
||||||
|
index 16f2ce6bea6f..8d2b8beb9a58 100644
|
||||||
|
--- a/llvm/lib/Target/ARM/ARMFrameLowering.h
|
||||||
|
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.h
|
||||||
|
@@ -59,6 +59,9 @@ public:
|
||||||
|
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
|
||||||
|
RegScavenger *RS) const override;
|
||||||
|
|
||||||
|
+ void processFunctionBeforeFrameFinalized(
|
||||||
|
+ MachineFunction &MF, RegScavenger *RS = nullptr) const override;
|
||||||
|
+
|
||||||
|
void adjustForSegmentedStacks(MachineFunction &MF,
|
||||||
|
MachineBasicBlock &MBB) const override;
|
||||||
|
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,116 @@
|
|||||||
|
From 369bfc8ea8c0a9da51b4bd964f0045cb389c3c2f Mon Sep 17 00:00:00 2001
|
||||||
|
From: ostannard <oliver.stannard@arm.com>
|
||||||
|
Date: Mon, 26 Feb 2024 12:23:25 +0000
|
||||||
|
Subject: [PATCH 3/3] [ARM] Update IsRestored for LR based on all returns
|
||||||
|
(#82745)
|
||||||
|
|
||||||
|
PR #75527 fixed ARMFrameLowering to set the IsRestored flag for LR based
|
||||||
|
on all of the return instructions in the function, not just one.
|
||||||
|
However, there is also code in ARMLoadStoreOptimizer which changes
|
||||||
|
return instructions, but it set IsRestored based on the one instruction
|
||||||
|
it changed, not the whole function.
|
||||||
|
|
||||||
|
The fix is to factor out the code added in #75527, and also call it from
|
||||||
|
ARMLoadStoreOptimizer if it made a change to return instructions.
|
||||||
|
|
||||||
|
Fixes #80287.
|
||||||
|
---
|
||||||
|
llvm/lib/Target/ARM/ARMFrameLowering.cpp | 11 +++++----
|
||||||
|
llvm/lib/Target/ARM/ARMFrameLowering.h | 4 ++++
|
||||||
|
llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp | 23 ++++++++-----------
|
||||||
|
3 files changed, 21 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
|
||||||
|
index 650f4650eef0..008ba4e5924b 100644
|
||||||
|
--- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp
|
||||||
|
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
|
||||||
|
@@ -2766,10 +2766,7 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
|
||||||
|
AFI->setLRIsSpilled(SavedRegs.test(ARM::LR));
|
||||||
|
}
|
||||||
|
|
||||||
|
-void ARMFrameLowering::processFunctionBeforeFrameFinalized(
|
||||||
|
- MachineFunction &MF, RegScavenger *RS) const {
|
||||||
|
- TargetFrameLowering::processFunctionBeforeFrameFinalized(MF, RS);
|
||||||
|
-
|
||||||
|
+void ARMFrameLowering::updateLRRestored(MachineFunction &MF) {
|
||||||
|
MachineFrameInfo &MFI = MF.getFrameInfo();
|
||||||
|
if (!MFI.isCalleeSavedInfoValid())
|
||||||
|
return;
|
||||||
|
@@ -2793,6 +2790,12 @@ void ARMFrameLowering::processFunctionBeforeFrameFinalized(
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+void ARMFrameLowering::processFunctionBeforeFrameFinalized(
|
||||||
|
+ MachineFunction &MF, RegScavenger *RS) const {
|
||||||
|
+ TargetFrameLowering::processFunctionBeforeFrameFinalized(MF, RS);
|
||||||
|
+ updateLRRestored(MF);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void ARMFrameLowering::getCalleeSaves(const MachineFunction &MF,
|
||||||
|
BitVector &SavedRegs) const {
|
||||||
|
TargetFrameLowering::getCalleeSaves(MF, SavedRegs);
|
||||||
|
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.h b/llvm/lib/Target/ARM/ARMFrameLowering.h
|
||||||
|
index 8d2b8beb9a58..3c7358d8cd53 100644
|
||||||
|
--- a/llvm/lib/Target/ARM/ARMFrameLowering.h
|
||||||
|
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.h
|
||||||
|
@@ -59,6 +59,10 @@ public:
|
||||||
|
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
|
||||||
|
RegScavenger *RS) const override;
|
||||||
|
|
||||||
|
+ /// Update the IsRestored flag on LR if it is spilled, based on the return
|
||||||
|
+ /// instructions.
|
||||||
|
+ static void updateLRRestored(MachineFunction &MF);
|
||||||
|
+
|
||||||
|
void processFunctionBeforeFrameFinalized(
|
||||||
|
MachineFunction &MF, RegScavenger *RS = nullptr) const override;
|
||||||
|
|
||||||
|
diff --git a/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
|
||||||
|
index 93db983b92c0..37d9e1addd1e 100644
|
||||||
|
--- a/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
|
||||||
|
+++ b/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
|
||||||
|
@@ -2062,17 +2062,6 @@ bool ARMLoadStoreOpt::MergeReturnIntoLDM(MachineBasicBlock &MBB) {
|
||||||
|
MO.setReg(ARM::PC);
|
||||||
|
PrevMI.copyImplicitOps(*MBB.getParent(), *MBBI);
|
||||||
|
MBB.erase(MBBI);
|
||||||
|
- // We now restore LR into PC so it is not live-out of the return block
|
||||||
|
- // anymore: Clear the CSI Restored bit.
|
||||||
|
- MachineFrameInfo &MFI = MBB.getParent()->getFrameInfo();
|
||||||
|
- // CSI should be fixed after PrologEpilog Insertion
|
||||||
|
- assert(MFI.isCalleeSavedInfoValid() && "CSI should be valid");
|
||||||
|
- for (CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) {
|
||||||
|
- if (Info.getReg() == ARM::LR) {
|
||||||
|
- Info.setRestored(false);
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -2120,14 +2109,22 @@ bool ARMLoadStoreOpt::runOnMachineFunction(MachineFunction &Fn) {
|
||||||
|
isThumb2 = AFI->isThumb2Function();
|
||||||
|
isThumb1 = AFI->isThumbFunction() && !isThumb2;
|
||||||
|
|
||||||
|
- bool Modified = false;
|
||||||
|
+ bool Modified = false, ModifiedLDMReturn = false;
|
||||||
|
for (MachineBasicBlock &MBB : Fn) {
|
||||||
|
Modified |= LoadStoreMultipleOpti(MBB);
|
||||||
|
if (STI->hasV5TOps() && !AFI->shouldSignReturnAddress())
|
||||||
|
- Modified |= MergeReturnIntoLDM(MBB);
|
||||||
|
+ ModifiedLDMReturn |= MergeReturnIntoLDM(MBB);
|
||||||
|
if (isThumb1)
|
||||||
|
Modified |= CombineMovBx(MBB);
|
||||||
|
}
|
||||||
|
+ Modified |= ModifiedLDMReturn;
|
||||||
|
+
|
||||||
|
+ // If we merged a BX instruction into an LDM, we need to re-calculate whether
|
||||||
|
+ // LR is restored. This check needs to consider the whole function, not just
|
||||||
|
+ // the instruction(s) we changed, because there may be other BX returns which
|
||||||
|
+ // still need LR to be restored.
|
||||||
|
+ if (ModifiedLDMReturn)
|
||||||
|
+ ARMFrameLowering::updateLRRestored(Fn);
|
||||||
|
|
||||||
|
Allocator.DestroyAll();
|
||||||
|
return Modified;
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
Name: %{pkg_name}
|
Name: %{pkg_name}
|
||||||
Version: %{maj_ver}.%{min_ver}.%{patch_ver}
|
Version: %{maj_ver}.%{min_ver}.%{patch_ver}
|
||||||
Release: 6
|
Release: 7
|
||||||
Summary: The Low Level Virtual Machine
|
Summary: The Low Level Virtual Machine
|
||||||
|
|
||||||
License: NCSA
|
License: NCSA
|
||||||
@ -62,6 +62,8 @@ Patch11: 0011-Backport-LoongArch-Add-the-support-for-vector-in-llvm17.patch
|
|||||||
Patch12: 0012-Backport-LoongArch-improve-the-support-for-compiler-rt-and-bugfix.patch
|
Patch12: 0012-Backport-LoongArch-improve-the-support-for-compiler-rt-and-bugfix.patch
|
||||||
Patch13: 0013-Backport-Bitcode-Add-some-missing-GetTypeByID-failure-checks.patch
|
Patch13: 0013-Backport-Bitcode-Add-some-missing-GetTypeByID-failure-checks.patch
|
||||||
Patch14: 0001-Backport-X86-Inline-Skip-inline-asm-in-inlining-targ.patch
|
Patch14: 0001-Backport-X86-Inline-Skip-inline-asm-in-inlining-targ.patch
|
||||||
|
Patch15: 0015-Backport-ARM-Check-all-terms-in-emitPopInst-when-clearing-Res.patch
|
||||||
|
Patch16: 0016-Backport-ARM-Update-IsRestored-for-LR-based-on-all-returns-82.patch
|
||||||
|
|
||||||
BuildRequires: binutils-devel
|
BuildRequires: binutils-devel
|
||||||
BuildRequires: cmake
|
BuildRequires: cmake
|
||||||
@ -344,6 +346,9 @@ LD_LIBRARY_PATH=%{buildroot}/%{install_libdir} %{__ninja} check-all -C ./_build
|
|||||||
%{install_includedir}/llvm-gmock
|
%{install_includedir}/llvm-gmock
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri Apr 12 2024 liyunfei <liyunfei33@huawei.com> - 17.0.6-6
|
||||||
|
- Backport patch to fix CVE-2024-31852
|
||||||
|
|
||||||
* Thu Apr 11 2024 wangqiang <wangqiang1@kylinos.cn> - 17.0.6-6
|
* Thu Apr 11 2024 wangqiang <wangqiang1@kylinos.cn> - 17.0.6-6
|
||||||
- Skip inline asm in inlining target feature check on X86
|
- Skip inline asm in inlining target feature check on X86
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user