-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[ARM] Avoid reference into modified vector #93965
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
FirstCand is a reference to RepeatedSequenceLocs[0]. However, that vector is being modified a lot throughout the function, including one place that reassigns the whole vector. I'm not sure whether this can really happen in practice, but it doesn't seem unlikely that this could lead to a use-after-free. Avoid this by directly using RepeatedSequenceLocs[0] at the start of the function (as a lot of other places already do) and only creating FirstCand at the end where no more modifications take place.
@llvm/pr-subscribers-backend-aarch64 @llvm/pr-subscribers-backend-arm Author: Nikita Popov (nikic) ChangesFirstCand is a reference to RepeatedSequenceLocs[0]. However, that vector is being modified a lot throughout the function, including one place that reassigns the whole vector. I'm not sure whether this can really happen in practice, but it doesn't seem unlikely that this could lead to a use-after-free. Avoid this by directly using RepeatedSequenceLocs[0] at the start of the function (as a lot of other places already do) and only creating FirstCand at the end where no more modifications take place. Full diff: https://github.com/llvm/llvm-project/pull/93965.diff 1 Files Affected:
diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
index 8f873bee484ac..627148b73c4f5 100644
--- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -5873,10 +5873,8 @@ static bool isLRAvailable(const TargetRegisterInfo &TRI,
std::optional<outliner::OutlinedFunction>
ARMBaseInstrInfo::getOutliningCandidateInfo(
std::vector<outliner::Candidate> &RepeatedSequenceLocs) const {
- outliner::Candidate &FirstCand = RepeatedSequenceLocs[0];
-
unsigned SequenceSize = 0;
- for (auto &MI : FirstCand)
+ for (auto &MI : RepeatedSequenceLocs[0])
SequenceSize += getInstSizeInBytes(MI);
// Properties about candidate MBBs that hold for all of them.
@@ -6071,6 +6069,7 @@ ARMBaseInstrInfo::getOutliningCandidateInfo(
if (FlagsSetInAll & MachineOutlinerMBBFlags::HasCalls) {
// check if the range contains a call. These require a save + restore of
// the link register.
+ outliner::Candidate &FirstCand = RepeatedSequenceLocs[0];
if (std::any_of(FirstCand.begin(), std::prev(FirstCand.end()),
[](const MachineInstr &MI) { return MI.isCall(); }))
NumBytesToCreateFrame += Costs.SaveRestoreLROnStack;
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks
Hi. This PR broke some tests downstream for us, using the ARM backend. |
@rgwott I'd love to have a reproducer for this -- it actually sounds like exactly the case I was concerned about here: RepeatedSequenceLocs gets reassigned to CandidatesWithoutStackFixups, while FirstCand still points into the old vector memory. If you run your test case under valgrind (or address sanitizer), do you maybe get a use-after-free report? I'd expect that to happen, if I'm not misunderstanding the code. In any case, I'd be happy to revert this change in the meantime if it's causing issues for you. |
@nikic here is a reproducer:
I did not see a use-after-free report in valgrind, but we do see this STL assertion: No rush to revert this change, as I reverted it downstream to keep on working and I can reapply it once a fix comes from upstream. |
The following code assumes that RepeatedSequenceLocs is non-empty. Bail out if there are less than 2 candidates left, as no outlining is possible in that case. The same check is already present in all the other places where elements from RepeatedSequenceLocs may be dropped. This fixes the issue reported at: llvm#93965 (comment)
) The following code assumes that RepeatedSequenceLocs is non-empty. Bail out if there are less than 2 candidates left, as no outlining is possible in that case. The same check is already present in all the other places where elements from RepeatedSequenceLocs may be dropped. This fixes the issue reported at: #93965 (comment)
…m#95410) The following code assumes that RepeatedSequenceLocs is non-empty. Bail out if there are less than 2 candidates left, as no outlining is possible in that case. The same check is already present in all the other places where elements from RepeatedSequenceLocs may be dropped. This fixes the issue reported at: llvm#93965 (comment)
FirstCand is a reference to RepeatedSequenceLocs[0]. However, that vector is being modified a lot throughout the function, including one place that reassigns the whole vector. I'm not sure whether this can really happen in practice, but it doesn't seem unlikely that this could lead to a use-after-free.
Avoid this by directly using RepeatedSequenceLocs[0] at the start of the function (as a lot of other places already do) and only creating FirstCand at the end where no more modifications take place.