From 856898e8939c22121cf30a88a52fce225c306ee0 Mon Sep 17 00:00:00 2001 From: liyunfei Date: Tue, 21 Jan 2025 17:29:35 +0800 Subject: [PATCH] Fix CVE-2024-7883 --- ...-when-CONTROL-S-SFPA-0-CVE-2024-7883.patch | 513 ++++++++++++++++++ llvm.spec | 6 +- 2 files changed, 518 insertions(+), 1 deletion(-) create mode 100644 0035-Backport-ARM-Fix-CMSE-S-NS-calls-when-CONTROL-S-SFPA-0-CVE-2024-7883.patch diff --git a/0035-Backport-ARM-Fix-CMSE-S-NS-calls-when-CONTROL-S-SFPA-0-CVE-2024-7883.patch b/0035-Backport-ARM-Fix-CMSE-S-NS-calls-when-CONTROL-S-SFPA-0-CVE-2024-7883.patch new file mode 100644 index 0000000..7f59320 --- /dev/null +++ b/0035-Backport-ARM-Fix-CMSE-S-NS-calls-when-CONTROL-S-SFPA-0-CVE-2024-7883.patch @@ -0,0 +1,513 @@ +From 5188abc4c0ab92102c023b01be26a9ad57492c4b Mon Sep 17 00:00:00 2001 +From: Oliver Stannard +Date: Fri, 1 Nov 2024 10:36:13 +0100 +Subject: [PATCH] [Backport][ARM] Fix CMSE S->NS calls when CONTROL_S.SFPA==0 + (CVE-2024-7883) (#114433) + +When doing a call from CMSE secure state to non-secure state for +v8-M.main, we use the VLLDM and VLSTM instructions to save, clear and +restore the FP registers around the call. These instructions both check +the CONTROL_S.SFPA bit, and if it is clear (meaning the current contents +of the FP registers are not secret) they execute as no-ops. + +This causes a problem when CONTROL_S.SFPA==0 before the call, which +happens if there are no floating-point instructions executed between +entry to secure state and the call. If this is the case, then the VLSTM +instruction will do nothing, leaving the save area in the stack +uninitialised. If the called function returns a value in floating-point +registers, the call sequence includes an instruction to copy the return +value from a floating-point register to a GPR, which must be before the +VLLDM instruction. This copy sets CONTROL_S.SFPA, meaning that the VLLDM +will fully execute, and load the uninitialised stack memory into the FP +registers. + +This causes two problems: +* The FP register file is clobbered, including all of the callee-saved + registers, which might contain live values. +* The stack region might contain secret values, which will be leaked to + non-secure state through the floating-point registers if/when we + return to non-secure state. + +The fix is to insert a `vmov s0, s0` instruction before the VLSTM +instruction, to ensure that CONTROL_S.SFPA is set for both the VLLDM and +VLSTM instruction. + +CVE: https://www.cve.org/cverecord?id=CVE-2024-7883 +Security bulletin: +https://developer.arm.com/Arm%20Security%20Center/Cortex-M%20Security%20Extensions%20Vulnerability +--- + llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp | 44 ++++- + .../test/CodeGen/ARM/cmse-clear-float-hard.ll | 160 ++++++++++++++---- + .../CodeGen/ARM/cmse-vlldm-no-reorder.mir | 1 + + 3 files changed, 172 insertions(+), 33 deletions(-) + +diff --git a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp +index 2f9236bb977f..1db4d410a467 100644 +--- a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp ++++ b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp +@@ -1429,6 +1429,7 @@ void ARMExpandPseudo::CMSESaveClearFPRegsV8( + // Use ScratchRegs to store the fp regs + std::vector> ClearedFPRegs; + std::vector NonclearedFPRegs; ++ bool ReturnsFPReg = false; + for (const MachineOperand &Op : MBBI->operands()) { + if (Op.isReg() && Op.isUse()) { + Register Reg = Op.getReg(); +@@ -1463,14 +1464,51 @@ void ARMExpandPseudo::CMSESaveClearFPRegsV8( + NonclearedFPRegs.push_back(Reg); + } + } ++ } else if (Op.isReg() && Op.isDef()) { ++ Register Reg = Op.getReg(); ++ if (ARM::SPRRegClass.contains(Reg) || ARM::DPRRegClass.contains(Reg) || ++ ARM::QPRRegClass.contains(Reg)) ++ ReturnsFPReg = true; + } + } + +- bool passesFPReg = (!NonclearedFPRegs.empty() || !ClearedFPRegs.empty()); ++ bool PassesFPReg = (!NonclearedFPRegs.empty() || !ClearedFPRegs.empty()); + +- if (passesFPReg) ++ if (PassesFPReg || ReturnsFPReg) + assert(STI->hasFPRegs() && "Subtarget needs fpregs"); + ++ // CVE-2024-7883 ++ // ++ // The VLLDM/VLSTM instructions set up lazy state preservation, but they ++ // execute as NOPs if the FP register file is not considered to contain ++ // secure data, represented by the CONTROL_S.SFPA bit. This means that the ++ // state of CONTROL_S.SFPA must be the same when these two instructions are ++ // executed. That might not be the case if we haven't used any FP ++ // instructions before the VLSTM, so CONTROL_S.SFPA is clear, but do have one ++ // before the VLLDM, which sets it.. ++ // ++ // If we can't prove that SFPA will be the same for the VLSTM and VLLDM, we ++ // execute a "vmov s0, s0" instruction before the VLSTM to ensure that ++ // CONTROL_S.SFPA is set for both. ++ // ++ // That can only happen for callees which take no FP arguments (or we'd have ++ // inserted a VMOV above) and which return values in FP regs (so that we need ++ // to use a VMOV to back-up the return value before the VLLDM). It also can't ++ // happen if the call is dominated by other existing floating-point ++ // instructions, but we don't currently check for that case. ++ // ++ // These conditions mean that we only emit this instruction when using the ++ // hard-float ABI, which means we can assume that FP instructions are ++ // available, and don't need to make it conditional like we do for the ++ // CVE-2021-35465 workaround. ++ if (ReturnsFPReg && !PassesFPReg) { ++ bool S0Dead = !LiveRegs.contains(ARM::S0); ++ BuildMI(MBB, MBBI, DL, TII->get(ARM::VMOVS)) ++ .addReg(ARM::S0, RegState::Define | getDeadRegState(S0Dead)) ++ .addReg(ARM::S0, getUndefRegState(S0Dead)) ++ .add(predOps(ARMCC::AL)); ++ } ++ + // Lazy store all fp registers to the stack. + // This executes as NOP in the absence of floating-point support. + MachineInstrBuilder VLSTM = BuildMI(MBB, MBBI, DL, TII->get(ARM::VLSTM)) +@@ -1525,7 +1563,7 @@ void ARMExpandPseudo::CMSESaveClearFPRegsV8( + } + // restore FPSCR from stack and clear bits 0-4, 7, 28-31 + // The other bits are program global according to the AAPCS +- if (passesFPReg) { ++ if (PassesFPReg) { + BuildMI(MBB, MBBI, DL, TII->get(ARM::tLDRspi), SpareReg) + .addReg(ARM::SP) + .addImm(0x10) +diff --git a/llvm/test/CodeGen/ARM/cmse-clear-float-hard.ll b/llvm/test/CodeGen/ARM/cmse-clear-float-hard.ll +index 606859db0a0e..f97fc51a0c45 100644 +--- a/llvm/test/CodeGen/ARM/cmse-clear-float-hard.ll ++++ b/llvm/test/CodeGen/ARM/cmse-clear-float-hard.ll +@@ -187,7 +187,7 @@ define float @f2(ptr nocapture %fptr) #2 { + ; CHECK-8M-NEXT: bic r0, r0, #1 + ; CHECK-8M-NEXT: sub sp, #136 + ; CHECK-8M-NEXT: vmov r12, s0 +-; CHECK-8M-NEXT: vlstm sp ++; CHECK-8M-NEXT: vlstm sp, {d0 - d15} + ; CHECK-8M-NEXT: vmov s0, r12 + ; CHECK-8M-NEXT: ldr r1, [sp, #64] + ; CHECK-8M-NEXT: bic r1, r1, #159 +@@ -207,7 +207,7 @@ define float @f2(ptr nocapture %fptr) #2 { + ; CHECK-8M-NEXT: msr apsr_nzcvqg, r0 + ; CHECK-8M-NEXT: blxns r0 + ; CHECK-8M-NEXT: vmov r12, s0 +-; CHECK-8M-NEXT: vlldm sp ++; CHECK-8M-NEXT: vlldm sp, {d0 - d15} + ; CHECK-8M-NEXT: vmov s0, r12 + ; CHECK-8M-NEXT: add sp, #136 + ; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} +@@ -245,7 +245,7 @@ define double @d2(ptr nocapture %fptr) #2 { + ; CHECK-8M-LE-NEXT: bic r0, r0, #1 + ; CHECK-8M-LE-NEXT: sub sp, #136 + ; CHECK-8M-LE-NEXT: vmov r11, r12, d0 +-; CHECK-8M-LE-NEXT: vlstm sp ++; CHECK-8M-LE-NEXT: vlstm sp, {d0 - d15} + ; CHECK-8M-LE-NEXT: vmov d0, r11, r12 + ; CHECK-8M-LE-NEXT: ldr r1, [sp, #64] + ; CHECK-8M-LE-NEXT: bic r1, r1, #159 +@@ -264,7 +264,7 @@ define double @d2(ptr nocapture %fptr) #2 { + ; CHECK-8M-LE-NEXT: msr apsr_nzcvqg, r0 + ; CHECK-8M-LE-NEXT: blxns r0 + ; CHECK-8M-LE-NEXT: vmov r11, r12, d0 +-; CHECK-8M-LE-NEXT: vlldm sp ++; CHECK-8M-LE-NEXT: vlldm sp, {d0 - d15} + ; CHECK-8M-LE-NEXT: vmov d0, r11, r12 + ; CHECK-8M-LE-NEXT: add sp, #136 + ; CHECK-8M-LE-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} +@@ -283,7 +283,7 @@ define double @d2(ptr nocapture %fptr) #2 { + ; CHECK-8M-BE-NEXT: bic r0, r0, #1 + ; CHECK-8M-BE-NEXT: sub sp, #136 + ; CHECK-8M-BE-NEXT: vmov r11, r12, d0 +-; CHECK-8M-BE-NEXT: vlstm sp ++; CHECK-8M-BE-NEXT: vlstm sp, {d0 - d15} + ; CHECK-8M-BE-NEXT: vmov d0, r11, r12 + ; CHECK-8M-BE-NEXT: ldr r1, [sp, #64] + ; CHECK-8M-BE-NEXT: bic r1, r1, #159 +@@ -302,7 +302,7 @@ define double @d2(ptr nocapture %fptr) #2 { + ; CHECK-8M-BE-NEXT: msr apsr_nzcvqg, r0 + ; CHECK-8M-BE-NEXT: blxns r0 + ; CHECK-8M-BE-NEXT: vmov r11, r12, d0 +-; CHECK-8M-BE-NEXT: vlldm sp ++; CHECK-8M-BE-NEXT: vlldm sp, {d0 - d15} + ; CHECK-8M-BE-NEXT: vmov d0, r11, r12 + ; CHECK-8M-BE-NEXT: add sp, #136 + ; CHECK-8M-BE-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} +@@ -368,7 +368,7 @@ define float @f3(ptr nocapture %fptr) #4 { + ; CHECK-8M-NEXT: bic r0, r0, #1 + ; CHECK-8M-NEXT: sub sp, #136 + ; CHECK-8M-NEXT: vmov r12, s0 +-; CHECK-8M-NEXT: vlstm sp ++; CHECK-8M-NEXT: vlstm sp, {d0 - d15} + ; CHECK-8M-NEXT: vmov s0, r12 + ; CHECK-8M-NEXT: ldr r1, [sp, #64] + ; CHECK-8M-NEXT: bic r1, r1, #159 +@@ -388,7 +388,7 @@ define float @f3(ptr nocapture %fptr) #4 { + ; CHECK-8M-NEXT: msr apsr_nzcvqg, r0 + ; CHECK-8M-NEXT: blxns r0 + ; CHECK-8M-NEXT: vmov r12, s0 +-; CHECK-8M-NEXT: vlldm sp ++; CHECK-8M-NEXT: vlldm sp, {d0 - d15} + ; CHECK-8M-NEXT: vmov s0, r12 + ; CHECK-8M-NEXT: add sp, #136 + ; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} +@@ -426,7 +426,7 @@ define double @d3(ptr nocapture %fptr) #4 { + ; CHECK-8M-LE-NEXT: bic r0, r0, #1 + ; CHECK-8M-LE-NEXT: sub sp, #136 + ; CHECK-8M-LE-NEXT: vmov r11, r12, d0 +-; CHECK-8M-LE-NEXT: vlstm sp ++; CHECK-8M-LE-NEXT: vlstm sp, {d0 - d15} + ; CHECK-8M-LE-NEXT: vmov d0, r11, r12 + ; CHECK-8M-LE-NEXT: ldr r1, [sp, #64] + ; CHECK-8M-LE-NEXT: bic r1, r1, #159 +@@ -445,7 +445,7 @@ define double @d3(ptr nocapture %fptr) #4 { + ; CHECK-8M-LE-NEXT: msr apsr_nzcvqg, r0 + ; CHECK-8M-LE-NEXT: blxns r0 + ; CHECK-8M-LE-NEXT: vmov r11, r12, d0 +-; CHECK-8M-LE-NEXT: vlldm sp ++; CHECK-8M-LE-NEXT: vlldm sp, {d0 - d15} + ; CHECK-8M-LE-NEXT: vmov d0, r11, r12 + ; CHECK-8M-LE-NEXT: add sp, #136 + ; CHECK-8M-LE-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} +@@ -464,7 +464,7 @@ define double @d3(ptr nocapture %fptr) #4 { + ; CHECK-8M-BE-NEXT: bic r0, r0, #1 + ; CHECK-8M-BE-NEXT: sub sp, #136 + ; CHECK-8M-BE-NEXT: vmov r11, r12, d0 +-; CHECK-8M-BE-NEXT: vlstm sp ++; CHECK-8M-BE-NEXT: vlstm sp, {d0 - d15} + ; CHECK-8M-BE-NEXT: vmov d0, r11, r12 + ; CHECK-8M-BE-NEXT: ldr r1, [sp, #64] + ; CHECK-8M-BE-NEXT: bic r1, r1, #159 +@@ -483,7 +483,7 @@ define double @d3(ptr nocapture %fptr) #4 { + ; CHECK-8M-BE-NEXT: msr apsr_nzcvqg, r0 + ; CHECK-8M-BE-NEXT: blxns r0 + ; CHECK-8M-BE-NEXT: vmov r11, r12, d0 +-; CHECK-8M-BE-NEXT: vlldm sp ++; CHECK-8M-BE-NEXT: vlldm sp, {d0 - d15} + ; CHECK-8M-BE-NEXT: vmov d0, r11, r12 + ; CHECK-8M-BE-NEXT: add sp, #136 + ; CHECK-8M-BE-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} +@@ -547,8 +547,9 @@ define float @f4(ptr nocapture %fptr) #6 { + ; CHECK-8M-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11} + ; CHECK-8M-NEXT: bic r0, r0, #1 + ; CHECK-8M-NEXT: sub sp, #136 +-; CHECK-8M-NEXT: vlstm sp ++; CHECK-8M-NEXT: vmov.f32 s0, s0 + ; CHECK-8M-NEXT: mov r1, r0 ++; CHECK-8M-NEXT: vlstm sp, {d0 - d15} + ; CHECK-8M-NEXT: mov r2, r0 + ; CHECK-8M-NEXT: mov r3, r0 + ; CHECK-8M-NEXT: mov r4, r0 +@@ -563,7 +564,7 @@ define float @f4(ptr nocapture %fptr) #6 { + ; CHECK-8M-NEXT: msr apsr_nzcvqg, r0 + ; CHECK-8M-NEXT: blxns r0 + ; CHECK-8M-NEXT: vmov r12, s0 +-; CHECK-8M-NEXT: vlldm sp ++; CHECK-8M-NEXT: vlldm sp, {d0 - d15} + ; CHECK-8M-NEXT: vmov s0, r12 + ; CHECK-8M-NEXT: add sp, #136 + ; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} +@@ -598,8 +599,9 @@ define double @d4(ptr nocapture %fptr) #6 { + ; CHECK-8M-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11} + ; CHECK-8M-NEXT: bic r0, r0, #1 + ; CHECK-8M-NEXT: sub sp, #136 +-; CHECK-8M-NEXT: vlstm sp ++; CHECK-8M-NEXT: vmov.f32 s0, s0 + ; CHECK-8M-NEXT: mov r1, r0 ++; CHECK-8M-NEXT: vlstm sp, {d0 - d15} + ; CHECK-8M-NEXT: mov r2, r0 + ; CHECK-8M-NEXT: mov r3, r0 + ; CHECK-8M-NEXT: mov r4, r0 +@@ -614,7 +616,7 @@ define double @d4(ptr nocapture %fptr) #6 { + ; CHECK-8M-NEXT: msr apsr_nzcvqg, r0 + ; CHECK-8M-NEXT: blxns r0 + ; CHECK-8M-NEXT: vmov r11, r12, d0 +-; CHECK-8M-NEXT: vlldm sp ++; CHECK-8M-NEXT: vlldm sp, {d0 - d15} + ; CHECK-8M-NEXT: vmov d0, r11, r12 + ; CHECK-8M-NEXT: add sp, #136 + ; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} +@@ -649,7 +651,7 @@ define void @fd(ptr %f, float %a, double %b) #8 { + ; CHECK-8M-NEXT: vmov r12, s0 + ; CHECK-8M-NEXT: mov r2, r0 + ; CHECK-8M-NEXT: vmov r10, r11, d1 +-; CHECK-8M-NEXT: vlstm sp ++; CHECK-8M-NEXT: vlstm sp, {d0 - d15} + ; CHECK-8M-NEXT: vmov s0, r12 + ; CHECK-8M-NEXT: vmov d1, r10, r11 + ; CHECK-8M-NEXT: ldr r1, [sp, #64] +@@ -666,7 +668,7 @@ define void @fd(ptr %f, float %a, double %b) #8 { + ; CHECK-8M-NEXT: mov r9, r0 + ; CHECK-8M-NEXT: msr apsr_nzcvqg, r0 + ; CHECK-8M-NEXT: blxns r0 +-; CHECK-8M-NEXT: vlldm sp ++; CHECK-8M-NEXT: vlldm sp, {d0 - d15} + ; CHECK-8M-NEXT: add sp, #136 + ; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} + ; CHECK-8M-NEXT: pop {r7, pc} +@@ -708,7 +710,7 @@ define void @fdff(ptr %f, float %a, double %b, float %c, float %d) #8 { + ; CHECK-8M-NEXT: vmov r9, s1 + ; CHECK-8M-NEXT: mov r4, r0 + ; CHECK-8M-NEXT: vmov r8, s4 +-; CHECK-8M-NEXT: vlstm sp ++; CHECK-8M-NEXT: vlstm sp, {d0 - d15} + ; CHECK-8M-NEXT: vmov s0, r12 + ; CHECK-8M-NEXT: vmov d1, r10, r11 + ; CHECK-8M-NEXT: vmov s1, r9 +@@ -723,7 +725,7 @@ define void @fdff(ptr %f, float %a, double %b, float %c, float %d) #8 { + ; CHECK-8M-NEXT: mov r7, r0 + ; CHECK-8M-NEXT: msr apsr_nzcvqg, r0 + ; CHECK-8M-NEXT: blxns r0 +-; CHECK-8M-NEXT: vlldm sp ++; CHECK-8M-NEXT: vlldm sp, {d0 - d15} + ; CHECK-8M-NEXT: add sp, #136 + ; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} + ; CHECK-8M-NEXT: pop {r7, pc} +@@ -765,7 +767,7 @@ define void @fidififid(ptr %fu, float %a, i32 %b, double %c, i32 %d, float %e, i + ; CHECK-8M-NEXT: vmov r8, s1 + ; CHECK-8M-NEXT: vmov r7, s4 + ; CHECK-8M-NEXT: vmov r5, r6, d3 +-; CHECK-8M-NEXT: vlstm sp ++; CHECK-8M-NEXT: vlstm sp, {d0 - d15} + ; CHECK-8M-NEXT: vmov s0, r11 + ; CHECK-8M-NEXT: vmov d1, r9, r10 + ; CHECK-8M-NEXT: vmov s1, r8 +@@ -778,7 +780,7 @@ define void @fidififid(ptr %fu, float %a, i32 %b, double %c, i32 %d, float %e, i + ; CHECK-8M-NEXT: mov r4, r12 + ; CHECK-8M-NEXT: msr apsr_nzcvqg, r12 + ; CHECK-8M-NEXT: blxns r12 +-; CHECK-8M-NEXT: vlldm sp ++; CHECK-8M-NEXT: vlldm sp, {d0 - d15} + ; CHECK-8M-NEXT: add sp, #136 + ; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} + ; CHECK-8M-NEXT: pop {r7, pc} +@@ -897,7 +899,7 @@ define half @h2(ptr nocapture %hptr) nounwind { + ; CHECK-8M-NEXT: bic r0, r0, #1 + ; CHECK-8M-NEXT: sub sp, #136 + ; CHECK-8M-NEXT: vmov r12, s0 +-; CHECK-8M-NEXT: vlstm sp ++; CHECK-8M-NEXT: vlstm sp, {d0 - d15} + ; CHECK-8M-NEXT: vmov s0, r12 + ; CHECK-8M-NEXT: ldr r1, [sp, #64] + ; CHECK-8M-NEXT: bic r1, r1, #159 +@@ -917,7 +919,7 @@ define half @h2(ptr nocapture %hptr) nounwind { + ; CHECK-8M-NEXT: msr apsr_nzcvqg, r0 + ; CHECK-8M-NEXT: blxns r0 + ; CHECK-8M-NEXT: vmov r12, s0 +-; CHECK-8M-NEXT: vlldm sp ++; CHECK-8M-NEXT: vlldm sp, {d0 - d15} + ; CHECK-8M-NEXT: vmov s0, r12 + ; CHECK-8M-NEXT: add sp, #136 + ; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} +@@ -976,7 +978,7 @@ define half @h3(ptr nocapture %hptr) nounwind { + ; CHECK-8M-NEXT: bic r0, r0, #1 + ; CHECK-8M-NEXT: sub sp, #136 + ; CHECK-8M-NEXT: vmov r12, s0 +-; CHECK-8M-NEXT: vlstm sp ++; CHECK-8M-NEXT: vlstm sp, {d0 - d15} + ; CHECK-8M-NEXT: vmov s0, r12 + ; CHECK-8M-NEXT: ldr r1, [sp, #64] + ; CHECK-8M-NEXT: bic r1, r1, #159 +@@ -996,7 +998,7 @@ define half @h3(ptr nocapture %hptr) nounwind { + ; CHECK-8M-NEXT: msr apsr_nzcvqg, r0 + ; CHECK-8M-NEXT: blxns r0 + ; CHECK-8M-NEXT: vmov r12, s0 +-; CHECK-8M-NEXT: vlldm sp ++; CHECK-8M-NEXT: vlldm sp, {d0 - d15} + ; CHECK-8M-NEXT: vmov s0, r12 + ; CHECK-8M-NEXT: add sp, #136 + ; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} +@@ -1053,8 +1055,9 @@ define half @h4(ptr nocapture %hptr) nounwind { + ; CHECK-8M-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11} + ; CHECK-8M-NEXT: bic r0, r0, #1 + ; CHECK-8M-NEXT: sub sp, #136 +-; CHECK-8M-NEXT: vlstm sp ++; CHECK-8M-NEXT: vmov.f32 s0, s0 + ; CHECK-8M-NEXT: mov r1, r0 ++; CHECK-8M-NEXT: vlstm sp, {d0 - d15} + ; CHECK-8M-NEXT: mov r2, r0 + ; CHECK-8M-NEXT: mov r3, r0 + ; CHECK-8M-NEXT: mov r4, r0 +@@ -1069,7 +1072,7 @@ define half @h4(ptr nocapture %hptr) nounwind { + ; CHECK-8M-NEXT: msr apsr_nzcvqg, r0 + ; CHECK-8M-NEXT: blxns r0 + ; CHECK-8M-NEXT: vmov r12, s0 +-; CHECK-8M-NEXT: vlldm sp ++; CHECK-8M-NEXT: vlldm sp, {d0 - d15} + ; CHECK-8M-NEXT: vmov s0, r12 + ; CHECK-8M-NEXT: add sp, #136 + ; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} +@@ -1176,7 +1179,7 @@ define half @h1_arg(ptr nocapture %hptr, half %harg) nounwind { + ; CHECK-8M-NEXT: bic r0, r0, #1 + ; CHECK-8M-NEXT: sub sp, #136 + ; CHECK-8M-NEXT: vmov r12, s0 +-; CHECK-8M-NEXT: vlstm sp ++; CHECK-8M-NEXT: vlstm sp, {d0 - d15} + ; CHECK-8M-NEXT: vmov s0, r12 + ; CHECK-8M-NEXT: ldr r1, [sp, #64] + ; CHECK-8M-NEXT: bic r1, r1, #159 +@@ -1196,7 +1199,7 @@ define half @h1_arg(ptr nocapture %hptr, half %harg) nounwind { + ; CHECK-8M-NEXT: msr apsr_nzcvqg, r0 + ; CHECK-8M-NEXT: blxns r0 + ; CHECK-8M-NEXT: vmov r12, s0 +-; CHECK-8M-NEXT: vlldm sp ++; CHECK-8M-NEXT: vlldm sp, {d0 - d15} + ; CHECK-8M-NEXT: vmov s0, r12 + ; CHECK-8M-NEXT: add sp, #136 + ; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} +@@ -1241,3 +1244,100 @@ entry: + ret half %call + } + ++define float @float_return_undef_arg(ptr nocapture %fptr) #6 { ++; CHECK-8M-LABEL: float_return_undef_arg: ++; CHECK-8M: @ %bb.0: @ %entry ++; CHECK-8M-NEXT: push {r7, lr} ++; CHECK-8M-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11} ++; CHECK-8M-NEXT: bic r0, r0, #1 ++; CHECK-8M-NEXT: sub sp, #136 ++; CHECK-8M-NEXT: vmov.f32 s0, s0 ++; CHECK-8M-NEXT: mov r1, r0 ++; CHECK-8M-NEXT: vlstm sp, {d0 - d15} ++; CHECK-8M-NEXT: mov r2, r0 ++; CHECK-8M-NEXT: mov r3, r0 ++; CHECK-8M-NEXT: mov r4, r0 ++; CHECK-8M-NEXT: mov r5, r0 ++; CHECK-8M-NEXT: mov r6, r0 ++; CHECK-8M-NEXT: mov r7, r0 ++; CHECK-8M-NEXT: mov r8, r0 ++; CHECK-8M-NEXT: mov r9, r0 ++; CHECK-8M-NEXT: mov r10, r0 ++; CHECK-8M-NEXT: mov r11, r0 ++; CHECK-8M-NEXT: mov r12, r0 ++; CHECK-8M-NEXT: msr apsr_nzcvqg, r0 ++; CHECK-8M-NEXT: blxns r0 ++; CHECK-8M-NEXT: vmov r12, s0 ++; CHECK-8M-NEXT: vlldm sp, {d0 - d15} ++; CHECK-8M-NEXT: vmov s0, r12 ++; CHECK-8M-NEXT: add sp, #136 ++; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} ++; CHECK-8M-NEXT: pop {r7, pc} ++; ++; CHECK-81M-LABEL: float_return_undef_arg: ++; CHECK-81M: @ %bb.0: @ %entry ++; CHECK-81M-NEXT: push {r7, lr} ++; CHECK-81M-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11} ++; CHECK-81M-NEXT: bic r0, r0, #1 ++; CHECK-81M-NEXT: vpush {s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31} ++; CHECK-81M-NEXT: vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31, vpr} ++; CHECK-81M-NEXT: vstr fpcxts, [sp, #-8]! ++; CHECK-81M-NEXT: clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr} ++; CHECK-81M-NEXT: blxns r0 ++; CHECK-81M-NEXT: vldr fpcxts, [sp], #8 ++; CHECK-81M-NEXT: vpop {s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31} ++; CHECK-81M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} ++; CHECK-81M-NEXT: pop {r7, pc} ++entry: ++ %call = call float %fptr(i32 undef) #7 ++ ret float %call ++} ++ ++define float @float_return_poison_arg(ptr nocapture %fptr) #6 { ++; CHECK-8M-LABEL: float_return_poison_arg: ++; CHECK-8M: @ %bb.0: @ %entry ++; CHECK-8M-NEXT: push {r7, lr} ++; CHECK-8M-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11} ++; CHECK-8M-NEXT: bic r0, r0, #1 ++; CHECK-8M-NEXT: sub sp, #136 ++; CHECK-8M-NEXT: vmov.f32 s0, s0 ++; CHECK-8M-NEXT: mov r1, r0 ++; CHECK-8M-NEXT: vlstm sp, {d0 - d15} ++; CHECK-8M-NEXT: mov r2, r0 ++; CHECK-8M-NEXT: mov r3, r0 ++; CHECK-8M-NEXT: mov r4, r0 ++; CHECK-8M-NEXT: mov r5, r0 ++; CHECK-8M-NEXT: mov r6, r0 ++; CHECK-8M-NEXT: mov r7, r0 ++; CHECK-8M-NEXT: mov r8, r0 ++; CHECK-8M-NEXT: mov r9, r0 ++; CHECK-8M-NEXT: mov r10, r0 ++; CHECK-8M-NEXT: mov r11, r0 ++; CHECK-8M-NEXT: mov r12, r0 ++; CHECK-8M-NEXT: msr apsr_nzcvqg, r0 ++; CHECK-8M-NEXT: blxns r0 ++; CHECK-8M-NEXT: vmov r12, s0 ++; CHECK-8M-NEXT: vlldm sp, {d0 - d15} ++; CHECK-8M-NEXT: vmov s0, r12 ++; CHECK-8M-NEXT: add sp, #136 ++; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} ++; CHECK-8M-NEXT: pop {r7, pc} ++; ++; CHECK-81M-LABEL: float_return_poison_arg: ++; CHECK-81M: @ %bb.0: @ %entry ++; CHECK-81M-NEXT: push {r7, lr} ++; CHECK-81M-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11} ++; CHECK-81M-NEXT: bic r0, r0, #1 ++; CHECK-81M-NEXT: vpush {s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31} ++; CHECK-81M-NEXT: vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31, vpr} ++; CHECK-81M-NEXT: vstr fpcxts, [sp, #-8]! ++; CHECK-81M-NEXT: clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr} ++; CHECK-81M-NEXT: blxns r0 ++; CHECK-81M-NEXT: vldr fpcxts, [sp], #8 ++; CHECK-81M-NEXT: vpop {s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31} ++; CHECK-81M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11} ++; CHECK-81M-NEXT: pop {r7, pc} ++entry: ++ %call = call float %fptr(i32 poison) #7 ++ ret float %call ++} +diff --git a/llvm/test/CodeGen/ARM/cmse-vlldm-no-reorder.mir b/llvm/test/CodeGen/ARM/cmse-vlldm-no-reorder.mir +index 2bc4288884f1..416cf3a53c9b 100644 +--- a/llvm/test/CodeGen/ARM/cmse-vlldm-no-reorder.mir ++++ b/llvm/test/CodeGen/ARM/cmse-vlldm-no-reorder.mir +@@ -89,6 +89,7 @@ body: | + # CHECK: $sp = t2STMDB_UPD $sp, 14 /* CC::al */, $noreg, $r4, $r5, $r6, undef $r7, $r8, $r9, $r10, $r11 + # CHECK-NEXT: $r0 = t2BICri $r0, 1, 14 /* CC::al */, $noreg, $noreg + # CHECK-NEXT: $sp = tSUBspi $sp, 34, 14 /* CC::al */, $noreg ++# CHECK-NEXT: dead $s0 = VMOVS undef $s0, 14 /* CC::al */, $noreg + # CHECK-NEXT: VLSTM $sp, 14 /* CC::al */, $noreg, implicit undef $vpr, implicit undef $fpscr, implicit undef $fpscr_nzcv, implicit undef $q0, implicit undef $q1, implicit undef $q2, implicit undef $q3, implicit undef $q4, implicit undef $q5, implicit undef $q6, implicit undef $q7 + # CHECK-NEXT: $r1 = tMOVr $r0, 14 /* CC::al */, $noreg + # CHECK-NEXT: $r2 = tMOVr $r0, 14 /* CC::al */, $noreg +-- +Gitee diff --git a/llvm.spec b/llvm.spec index d64b51f..9fd35b4 100644 --- a/llvm.spec +++ b/llvm.spec @@ -47,7 +47,7 @@ Name: %{pkg_name} Version: %{maj_ver}.%{min_ver}.%{patch_ver} -Release: 29 +Release: 30 Summary: The Low Level Virtual Machine License: NCSA @@ -92,6 +92,7 @@ Patch31: 0031-ACPO-ACPO-Infrastructure.patch Patch32: 0032-ACPO-Introduce-MLInliner-using-ACPO-infrastructure.patch Patch33: 0033-Find-Python3-in-default-env-PATH-for-ACPO.patch Patch34: 0034-AArch64-Support-HiSilicon-s-HIP09-sched-model.patch +Patch35: 0035-Backport-ARM-Fix-CMSE-S-NS-calls-when-CONTROL-S-SFPA-0-CVE-2024-7883.patch BuildRequires: binutils-devel BuildRequires: cmake @@ -391,6 +392,9 @@ LD_LIBRARY_PATH=%{buildroot}/%{install_libdir} %{__ninja} check-all -C %{__cmake %{install_includedir}/llvm-gmock %changelog +* Tue Jan 21 2025 liyunfei - 17.0.6-30 +- Fix CVE-2024-7883 + * Fri Nov 22 2024 xiajingze - 17.0.6-29 - [AArch64] Support HiSilicon's HIP09 sched model -- Gitee