Skip to content

Commit c595d61

Browse files
[AUTO-CHERRYPICK] Patch rust for CVE-2024-31852 and CVE-2024-32884 - branch main (#10126)
Co-authored-by: corvus-callidus <108946721+corvus-callidus@users.noreply.github.com>
1 parent 368eaf2 commit c595d61

3 files changed

Lines changed: 715 additions & 1 deletion

File tree

SPECS/rust/CVE-2024-31852.patch

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
Modified for Mariner by corvus-callidus:
2+
Removed changes to non-vendored files
3+
Fixed paths to match vendored code
4+
Backported patch to apply to version shipped with rust package
5+
Adjusted checksums to account for applied patches
6+
7+
From b1a5ee1febd8a903cec3dfdad61d57900dc3823e Mon Sep 17 00:00:00 2001
8+
From: Florian Hahn <flo@fhahn.com>
9+
Date: Wed, 20 Dec 2023 16:56:15 +0100
10+
Subject: [PATCH] [ARM] Check all terms in emitPopInst when clearing Restored
11+
for LR. (#75527)
12+
13+
emitPopInst checks a single function exit MBB. If other paths also exit
14+
the function and any of there terminators uses LR implicitly, it is not
15+
save to clear the Restored bit.
16+
17+
Check all terminators for the function before clearing Restored.
18+
19+
This fixes a mis-compile in outlined-fn-may-clobber-lr-in-caller.ll
20+
where the machine-outliner previously introduced BLs that clobbered LR
21+
which in turn is used by the tail call return.
22+
23+
Alternative to #73553
24+
---
25+
src/llvm-project/llvm/lib/Target/ARM/ARMFrameLowering.cpp | 30 +++++++++++++++++--
26+
src/llvm-project/llvm/lib/Target/ARM/ARMFrameLowering.h | 3 ++
27+
.../outlined-fn-may-clobber-lr-in-caller.ll | 14 ++++++---
28+
3 files changed, 40 insertions(+), 7 deletions(-)
29+
30+
diff --git a/src/llvm-project/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/src/llvm-project/llvm/lib/Target/ARM/ARMFrameLowering.cpp
31+
index a3a71a8ec09a4..10d9c7f275beb 100644
32+
--- a/src/llvm-project/llvm/lib/Target/ARM/ARMFrameLowering.cpp
33+
+++ b/src/llvm-project/llvm/lib/Target/ARM/ARMFrameLowering.cpp
34+
@@ -1645,9 +1645,6 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
35+
// Fold the return instruction into the LDM.
36+
DeleteRet = true;
37+
LdmOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_RET : ARM::LDMIA_RET;
38+
- // We 'restore' LR into PC so it is not live out of the return block:
39+
- // Clear Restored bit.
40+
- Info.setRestored(false);
41+
}
42+
43+
// If NoGap is true, pop consecutive registers and then leave the rest
44+
@@ -2785,6 +2782,33 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
45+
AFI->setLRIsSpilled(SavedRegs.test(ARM::LR));
46+
}
47+
48+
+void ARMFrameLowering::processFunctionBeforeFrameFinalized(
49+
+ MachineFunction &MF, RegScavenger *RS) const {
50+
+ TargetFrameLowering::processFunctionBeforeFrameFinalized(MF, RS);
51+
+
52+
+ MachineFrameInfo &MFI = MF.getFrameInfo();
53+
+ if (!MFI.isCalleeSavedInfoValid())
54+
+ return;
55+
+
56+
+ // Check if all terminators do not implicitly use LR. Then we can 'restore' LR
57+
+ // into PC so it is not live out of the return block: Clear the Restored bit
58+
+ // in that case.
59+
+ for (CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) {
60+
+ if (Info.getReg() != ARM::LR)
61+
+ continue;
62+
+ if (all_of(MF, [](const MachineBasicBlock &MBB) {
63+
+ return all_of(MBB.terminators(), [](const MachineInstr &Term) {
64+
+ return !Term.isReturn() || Term.getOpcode() == ARM::LDMIA_RET ||
65+
+ Term.getOpcode() == ARM::t2LDMIA_RET ||
66+
+ Term.getOpcode() == ARM::tPOP_RET;
67+
+ });
68+
+ })) {
69+
+ Info.setRestored(false);
70+
+ break;
71+
+ }
72+
+ }
73+
+}
74+
+
75+
void ARMFrameLowering::getCalleeSaves(const MachineFunction &MF,
76+
BitVector &SavedRegs) const {
77+
TargetFrameLowering::getCalleeSaves(MF, SavedRegs);
78+
diff --git a/src/llvm-project/llvm/lib/Target/ARM/ARMFrameLowering.h b/src/llvm-project/llvm/lib/Target/ARM/ARMFrameLowering.h
79+
index 16f2ce6bea6f1..8d2b8beb9a58f 100644
80+
--- a/src/llvm-project/llvm/lib/Target/ARM/ARMFrameLowering.h
81+
+++ b/src/llvm-project/llvm/lib/Target/ARM/ARMFrameLowering.h
82+
@@ -59,6 +59,9 @@ class ARMFrameLowering : public TargetFrameLowering {
83+
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
84+
RegScavenger *RS) const override;
85+
86+
+ void processFunctionBeforeFrameFinalized(
87+
+ MachineFunction &MF, RegScavenger *RS = nullptr) const override;
88+
+
89+
void adjustForSegmentedStacks(MachineFunction &MF,
90+
MachineBasicBlock &MBB) const override;
91+
92+
93+
From 749384c08e042739342c88b521c8ba5dac1b9276 Mon Sep 17 00:00:00 2001
94+
From: ostannard <oliver.stannard@arm.com>
95+
Date: Mon, 26 Feb 2024 12:23:25 +0000
96+
Subject: [PATCH] [ARM] Update IsRestored for LR based on all returns (#82745)
97+
98+
PR #75527 fixed ARMFrameLowering to set the IsRestored flag for LR based
99+
on all of the return instructions in the function, not just one.
100+
However, there is also code in ARMLoadStoreOptimizer which changes
101+
return instructions, but it set IsRestored based on the one instruction
102+
it changed, not the whole function.
103+
104+
The fix is to factor out the code added in #75527, and also call it from
105+
ARMLoadStoreOptimizer if it made a change to return instructions.
106+
107+
Fixes #80287.
108+
---
109+
src/llvm-project/llvm/lib/Target/ARM/ARMFrameLowering.cpp | 11 +++++----
110+
src/llvm-project/llvm/lib/Target/ARM/ARMFrameLowering.h | 4 ++++
111+
src/llvm-project/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp | 23 ++++++++-----------
112+
4 files changed, 27 insertions(+), 22 deletions(-)
113+
114+
diff --git a/src/llvm-project/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/src/llvm-project/llvm/lib/Target/ARM/ARMFrameLowering.cpp
115+
index eeb7f64aa5810..9b54dd4e4e618 100644
116+
--- a/src/llvm-project/llvm/lib/Target/ARM/ARMFrameLowering.cpp
117+
+++ b/src/llvm-project/llvm/lib/Target/ARM/ARMFrameLowering.cpp
118+
@@ -2781,10 +2781,7 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
119+
AFI->setLRIsSpilled(SavedRegs.test(ARM::LR));
120+
}
121+
122+
-void ARMFrameLowering::processFunctionBeforeFrameFinalized(
123+
- MachineFunction &MF, RegScavenger *RS) const {
124+
- TargetFrameLowering::processFunctionBeforeFrameFinalized(MF, RS);
125+
-
126+
+void ARMFrameLowering::updateLRRestored(MachineFunction &MF) {
127+
MachineFrameInfo &MFI = MF.getFrameInfo();
128+
if (!MFI.isCalleeSavedInfoValid())
129+
return;
130+
@@ -2808,6 +2805,12 @@ void ARMFrameLowering::processFunctionBeforeFrameFinalized(
131+
}
132+
}
133+
134+
+void ARMFrameLowering::processFunctionBeforeFrameFinalized(
135+
+ MachineFunction &MF, RegScavenger *RS) const {
136+
+ TargetFrameLowering::processFunctionBeforeFrameFinalized(MF, RS);
137+
+ updateLRRestored(MF);
138+
+}
139+
+
140+
void ARMFrameLowering::getCalleeSaves(const MachineFunction &MF,
141+
BitVector &SavedRegs) const {
142+
TargetFrameLowering::getCalleeSaves(MF, SavedRegs);
143+
diff --git a/src/llvm-project/llvm/lib/Target/ARM/ARMFrameLowering.h b/src/llvm-project/llvm/lib/Target/ARM/ARMFrameLowering.h
144+
index 8d2b8beb9a58f..3c7358d8cd53e 100644
145+
--- a/src/llvm-project/llvm/lib/Target/ARM/ARMFrameLowering.h
146+
+++ b/src/llvm-project/llvm/lib/Target/ARM/ARMFrameLowering.h
147+
@@ -59,6 +59,10 @@ class ARMFrameLowering : public TargetFrameLowering {
148+
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
149+
RegScavenger *RS) const override;
150+
151+
+ /// Update the IsRestored flag on LR if it is spilled, based on the return
152+
+ /// instructions.
153+
+ static void updateLRRestored(MachineFunction &MF);
154+
+
155+
void processFunctionBeforeFrameFinalized(
156+
MachineFunction &MF, RegScavenger *RS = nullptr) const override;
157+
158+
diff --git a/src/llvm-project/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/src/llvm-project/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
159+
index ed9d30c3c3ab9..6121055eb0217 100644
160+
--- a/src/llvm-project/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
161+
+++ b/src/llvm-project/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
162+
@@ -2062,17 +2062,6 @@ bool ARMLoadStoreOpt::MergeReturnIntoLDM(MachineBasicBlock &MBB) {
163+
MO.setReg(ARM::PC);
164+
PrevMI.copyImplicitOps(*MBB.getParent(), *MBBI);
165+
MBB.erase(MBBI);
166+
- // We now restore LR into PC so it is not live-out of the return block
167+
- // anymore: Clear the CSI Restored bit.
168+
- MachineFrameInfo &MFI = MBB.getParent()->getFrameInfo();
169+
- // CSI should be fixed after PrologEpilog Insertion
170+
- assert(MFI.isCalleeSavedInfoValid() && "CSI should be valid");
171+
- for (CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) {
172+
- if (Info.getReg() == ARM::LR) {
173+
- Info.setRestored(false);
174+
- break;
175+
- }
176+
- }
177+
return true;
178+
}
179+
}
180+
@@ -2120,14 +2109,22 @@ bool ARMLoadStoreOpt::runOnMachineFunction(MachineFunction &Fn) {
181+
isThumb2 = AFI->isThumb2Function();
182+
isThumb1 = AFI->isThumbFunction() && !isThumb2;
183+
184+
- bool Modified = false;
185+
+ bool Modified = false, ModifiedLDMReturn = false;
186+
for (MachineBasicBlock &MBB : Fn) {
187+
Modified |= LoadStoreMultipleOpti(MBB);
188+
if (STI->hasV5TOps() && !AFI->shouldSignReturnAddress())
189+
- Modified |= MergeReturnIntoLDM(MBB);
190+
+ ModifiedLDMReturn |= MergeReturnIntoLDM(MBB);
191+
if (isThumb1)
192+
Modified |= CombineMovBx(MBB);
193+
}
194+
+ Modified |= ModifiedLDMReturn;
195+
+
196+
+ // If we merged a BX instruction into an LDM, we need to re-calculate whether
197+
+ // LR is restored. This check needs to consider the whole function, not just
198+
+ // the instruction(s) we changed, because there may be other BX returns which
199+
+ // still need LR to be restored.
200+
+ if (ModifiedLDMReturn)
201+
+ ARMFrameLowering::updateLRRestored(Fn);
202+
203+
Allocator.DestroyAll();
204+
return Modified;

0 commit comments

Comments
 (0)