Backport patch to fix CVE-2024-31852

reference:
b1a5ee1feb
and
749384c08e

Signed-off-by: liyunfei <liyunfei33@huawei.com>
This commit is contained in:
liyunfei 2024-04-12 18:00:49 +08:00
parent 1ec20fc5b1
commit 332fb03bb7
3 changed files with 209 additions and 1 deletions

View File

@ -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

View File

@ -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

View File

@ -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