From 74836b2d1d4740874378c349d001df1eebde7194 Mon Sep 17 00:00:00 2001 From: ChunyangWang Date: Tue, 15 Oct 2024 14:03:21 +0800 Subject: [PATCH] add fix patch for CVE-2023-4039 --- ...rn-register-handling-in-untyped_call.patch | 66 ++++++++++ 0117-aarch64-Fix-loose-ldpstp-check.patch | 119 ++++++++++++++++++ gcc.spec | 12 +- 3 files changed, 195 insertions(+), 2 deletions(-) create mode 100644 0116-aarch64-Fix-return-register-handling-in-untyped_call.patch create mode 100644 0117-aarch64-Fix-loose-ldpstp-check.patch diff --git a/0116-aarch64-Fix-return-register-handling-in-untyped_call.patch b/0116-aarch64-Fix-return-register-handling-in-untyped_call.patch new file mode 100644 index 0000000..0bddd1a --- /dev/null +++ b/0116-aarch64-Fix-return-register-handling-in-untyped_call.patch @@ -0,0 +1,66 @@ +From 38d0605ac8bc90324170041676fc05e7e595769e Mon Sep 17 00:00:00 2001 +From: Richard Sandiford +Date: Wed, 20 Sep 2023 11:13:19 +0100 +Subject: [PATCH] aarch64: Fix return register handling in untyped_call + +While working on another patch, I hit a problem with the aarch64 +expansion of untyped_call. The expander emits the usual: + + (set (mem ...) (reg resN)) + +instructions to store the result registers to memory, but it didn't +say in RTL where those resN results came from. This eventually led +to a failure of gcc.dg/torture/stackalign/builtin-return-2.c, +via regrename. + +This patch turns the untyped call from a plain call to a call_value, +to represent that the call returns (or might return) a useful value. +The patch also uses a PARALLEL return rtx to represent all the possible +return registers. + +gcc/ + * config/aarch64/aarch64.md (untyped_call): Emit a call_value + rather than a call. List each possible destination register + in the call pattern. + +(cherry picked from commit 629efe27744d13c3b83bbe8338b84c37c83dbe4f) +--- + gcc/config/aarch64/aarch64.md | 20 +++++++++++++++++++- + 1 file changed, 19 insertions(+), 1 deletion(-) + +diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md +index b9b3ba4f9164..cd568f3daa0f 100644 +--- a/gcc/config/aarch64/aarch64.md ++++ b/gcc/config/aarch64/aarch64.md +@@ -1159,9 +1159,27 @@ + { + int i; + ++ /* Generate a PARALLEL that contains all of the register results. ++ The offsets are somewhat arbitrary, since we don't know the ++ actual return type. The main thing we need to avoid is having ++ overlapping byte ranges, since those might give the impression ++ that two registers are known to have data in common. */ ++ rtvec rets = rtvec_alloc (XVECLEN (operands[2], 0)); ++ poly_int64 offset = 0; ++ for (i = 0; i < XVECLEN (operands[2], 0); i++) ++ { ++ rtx reg = SET_SRC (XVECEXP (operands[2], 0, i)); ++ gcc_assert (REG_P (reg)); ++ rtx offset_rtx = gen_int_mode (offset, Pmode); ++ rtx piece = gen_rtx_EXPR_LIST (VOIDmode, reg, offset_rtx); ++ RTVEC_ELT (rets, i) = piece; ++ offset += GET_MODE_SIZE (GET_MODE (reg)); ++ } ++ rtx ret = gen_rtx_PARALLEL (VOIDmode, rets); ++ + /* Untyped calls always use the default ABI. It's only possible to use + ABI variants if we know the type of the target function. */ +- emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx)); ++ emit_call_insn (gen_call_value (ret, operands[0], const0_rtx, const0_rtx)); + + for (i = 0; i < XVECLEN (operands[2], 0); i++) + { +-- +2.43.5 + diff --git a/0117-aarch64-Fix-loose-ldpstp-check.patch b/0117-aarch64-Fix-loose-ldpstp-check.patch new file mode 100644 index 0000000..756a444 --- /dev/null +++ b/0117-aarch64-Fix-loose-ldpstp-check.patch @@ -0,0 +1,119 @@ +From 74f99f1adc696f446115f36974a3f94f66294a53 Mon Sep 17 00:00:00 2001 +From: Richard Sandiford +Date: Wed, 20 Sep 2023 11:13:20 +0100 +Subject: [PATCH] aarch64: Fix loose ldpstp check [PR111411] + +aarch64_operands_ok_for_ldpstp contained the code: + + /* One of the memory accesses must be a mempair operand. + If it is not the first one, they need to be swapped by the + peephole. */ + if (!aarch64_mem_pair_operand (mem_1, GET_MODE (mem_1)) + && !aarch64_mem_pair_operand (mem_2, GET_MODE (mem_2))) + return false; + +But the requirement isn't just that one of the accesses must be a +valid mempair operand. It's that the lower access must be, since +that's the access that will be used for the instruction operand. + +gcc/ + PR target/111411 + * config/aarch64/aarch64.cc (aarch64_operands_ok_for_ldpstp): Require + the lower memory access to a mem-pair operand. + +gcc/testsuite/ + PR target/111411 + * gcc.dg/rtl/aarch64/pr111411.c: New test. + +(cherry picked from commit 2d38f45bcca62ca0c7afef4b579f82c5c2a01610) +--- + gcc/config/aarch64/aarch64.cc | 8 ++- + gcc/testsuite/gcc.dg/rtl/aarch64/pr111411.c | 57 +++++++++++++++++++++ + 2 files changed, 60 insertions(+), 5 deletions(-) + create mode 100644 gcc/testsuite/gcc.dg/rtl/aarch64/pr111411.c + +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index 96c3f48fdc49..a979accd90a9 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -26031,11 +26031,9 @@ aarch64_operands_ok_for_ldpstp (rtx *operands, bool load, + gcc_assert (known_eq (GET_MODE_SIZE (GET_MODE (mem_1)), + GET_MODE_SIZE (GET_MODE (mem_2)))); + +- /* One of the memory accesses must be a mempair operand. +- If it is not the first one, they need to be swapped by the +- peephole. */ +- if (!aarch64_mem_pair_operand (mem_1, GET_MODE (mem_1)) +- && !aarch64_mem_pair_operand (mem_2, GET_MODE (mem_2))) ++ /* The lower memory access must be a mem-pair operand. */ ++ rtx lower_mem = reversed ? mem_2 : mem_1; ++ if (!aarch64_mem_pair_operand (lower_mem, GET_MODE (lower_mem))) + return false; + + if (REG_P (reg_1) && FP_REGNUM_P (REGNO (reg_1))) +diff --git a/gcc/testsuite/gcc.dg/rtl/aarch64/pr111411.c b/gcc/testsuite/gcc.dg/rtl/aarch64/pr111411.c +new file mode 100644 +index 000000000000..ad07e9c6c893 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/rtl/aarch64/pr111411.c +@@ -0,0 +1,57 @@ ++/* { dg-do compile { target aarch64*-*-* } } */ ++/* { dg-require-effective-target lp64 } */ ++/* { dg-options "-O -fdisable-rtl-postreload -fpeephole2 -fno-schedule-fusion" } */ ++ ++extern int data[]; ++ ++void __RTL (startwith ("ira")) foo (void *ptr) ++{ ++ (function "foo" ++ (param "ptr" ++ (DECL_RTL (reg/v:DI <0> [ ptr ])) ++ (DECL_RTL_INCOMING (reg/v:DI x0 [ ptr ])) ++ ) ;; param "ptr" ++ (insn-chain ++ (block 2 ++ (edge-from entry (flags "FALLTHRU")) ++ (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK) ++ (insn 4 (set (reg:DI <0>) (reg:DI x0))) ++ (insn 5 (set (reg:DI <1>) ++ (plus:DI (reg:DI <0>) (const_int 768)))) ++ (insn 6 (set (mem:SI (plus:DI (reg:DI <0>) ++ (const_int 508)) [1 &data+508 S4 A4]) ++ (const_int 0))) ++ (insn 7 (set (mem:SI (plus:DI (reg:DI <1>) ++ (const_int -256)) [1 &data+512 S4 A4]) ++ (const_int 0))) ++ (edge-to exit (flags "FALLTHRU")) ++ ) ;; block 2 ++ ) ;; insn-chain ++ ) ;; function ++} ++ ++void __RTL (startwith ("ira")) bar (void *ptr) ++{ ++ (function "bar" ++ (param "ptr" ++ (DECL_RTL (reg/v:DI <0> [ ptr ])) ++ (DECL_RTL_INCOMING (reg/v:DI x0 [ ptr ])) ++ ) ;; param "ptr" ++ (insn-chain ++ (block 2 ++ (edge-from entry (flags "FALLTHRU")) ++ (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK) ++ (insn 4 (set (reg:DI <0>) (reg:DI x0))) ++ (insn 5 (set (reg:DI <1>) ++ (plus:DI (reg:DI <0>) (const_int 768)))) ++ (insn 6 (set (mem:SI (plus:DI (reg:DI <1>) ++ (const_int -256)) [1 &data+512 S4 A4]) ++ (const_int 0))) ++ (insn 7 (set (mem:SI (plus:DI (reg:DI <0>) ++ (const_int 508)) [1 &data+508 S4 A4]) ++ (const_int 0))) ++ (edge-to exit (flags "FALLTHRU")) ++ ) ;; block 2 ++ ) ;; insn-chain ++ ) ;; function ++} +-- +2.43.5 + diff --git a/gcc.spec b/gcc.spec index 904d180..525fb46 100644 --- a/gcc.spec +++ b/gcc.spec @@ -2,7 +2,7 @@ %global gcc_major 12 # Note, gcc_release must be integer, if you want to add suffixes to # %%{release}, append them after %%{gcc_release} on Release: line. -%global gcc_release 35 +%global gcc_release 36 %global _unpackaged_files_terminate_build 0 %global _performance_build 1 @@ -222,7 +222,8 @@ Patch112: 0112-aarch64-Simplify-probe-of-final-frame-allocation.patch Patch113: 0113-aarch64-Explicitly-record-probe-registers-in-frame-info.patch Patch114: 0114-aarch64-Remove-below-hard-fp-saved-regs-size.patch Patch115: 0115-aarch64-Make-stack-smash-canary-protect-saved-registers.patch - +Patch116: 0116-aarch64-Fix-return-register-handling-in-untyped_call.patch +Patch117: 0117-aarch64-Fix-loose-ldpstp-check.patch # Part 3000 ~ 4999 %ifarch loongarch64 @@ -912,6 +913,9 @@ not stable, so plugins must be rebuilt any time GCC is updated. %patch113 -p1 %patch114 -p1 %patch115 -p1 +%patch116 -p1 +%patch117 -p1 + %ifarch loongarch64 %patch3001 -p1 @@ -3314,6 +3318,10 @@ end %doc rpm.doc/changelogs/libcc1/ChangeLog* %changelog +* Mon Oct 21 2024 wangchunyang - 12.3.1-36 +- Type: Sync +- DESC: Sync bugfix for CVE-2023-4039 + * Fri Sep 6 2024 wangchunyang - 12.3.1-35 - Type: Sync - DESC: Sync patch for CVE-2023-4039 -- Gitee