From nobody Mon Oct 6 17:04:32 2025 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id AA04C2236F2; Sat, 19 Jul 2025 04:38:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752899882; cv=none; b=cRLyDlVoYtzBl8YLaLoCv7zCwsgBCTPnWuD/2DFdskqiXwGewpdiBX9sxp90m+1YHxqQIR9Q5PezS/52zSN+KgSHCBMSykw6N6r6hofbfBgISAWGOhLsf8Xo02dDPiCPIBhb6tl9dOIir6P7aWeAJJ169GBI/xv566O1xOf3zYU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752899882; c=relaxed/simple; bh=BXNQjR8ZVx9QHf4N0+b39YD6ruoQMQRnBRAwJ4rpC9I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=M8onZdm58zv7wcVkwIXk1Txoyyo2OjEpUtlYTrT20dMVE7ObH1XhuuOIPmNhsGRVvEuqvkqGzdIee/op1zAomeRcRdpYZNunR2+GBMxP8S0ZCXMrwoqaNzzeEc4VYlx/6e75Yrqqljfhz1QQLWN1qYoVIL652m7tcaej6lTX7+o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 0D8292444; Fri, 18 Jul 2025 21:37:53 -0700 (PDT) Received: from u200865.usa.arm.com (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id EAD763F66E; Fri, 18 Jul 2025 21:37:58 -0700 (PDT) From: Jeremy Linton To: linux-trace-kernel@vger.kernel.org Cc: linux-perf-users@vger.kernel.org, mhiramat@kernel.org, oleg@redhat.com, peterz@infradead.org, acme@kernel.org, namhyung@kernel.org, mark.rutland@arm.com, alexander.shishkin@linux.intel.com, jolsa@kernel.org, irogers@google.com, adrian.hunter@intel.com, kan.liang@linux.intel.com, thiago.bauermann@linaro.org, broonie@kernel.org, yury.khrustalev@arm.com, kristina.martsenko@arm.com, liaochang1@huawei.com, catalin.marinas@arm.com, will@kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Jeremy Linton Subject: [PATCH v4 5/8] arm64: probes: Add GCS support to bl/blr/ret Date: Fri, 18 Jul 2025 23:37:37 -0500 Message-ID: <20250719043740.4548-6-jeremy.linton@arm.com> X-Mailer: git-send-email 2.50.0 In-Reply-To: <20250719043740.4548-1-jeremy.linton@arm.com> References: <20250719043740.4548-1-jeremy.linton@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The arm64 probe simulation doesn't currently have logic in place to deal with GCS and this results in core dumps if probes are inserted at control flow locations. Fix-up bl, blr and ret to manipulate the shadow stack as needed. While we manipulate and validate the shadow stack correctly, the hardware provides additional security by only allowing GCS operations against pages which are marked to support GCS. For writing there is gcssttr() which enforces this, but there isn't an equivalent for reading. This means that uprobe users should be aware that probing on control flow instructions which require reading the shadow stack (ex: ret) offers lower security guarantees than what is achieved without the uprobe active. Signed-off-by: Jeremy Linton --- arch/arm64/kernel/probes/simulate-insn.c | 35 ++++++++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/arch/arm64/kernel/probes/simulate-insn.c b/arch/arm64/kernel/p= robes/simulate-insn.c index 09a0b36122d0..c75dce7bbe13 100644 --- a/arch/arm64/kernel/probes/simulate-insn.c +++ b/arch/arm64/kernel/probes/simulate-insn.c @@ -13,6 +13,7 @@ #include =20 #include "simulate-insn.h" +#include "asm/gcs.h" =20 #define bbl_displacement(insn) \ sign_extend32(((insn) & 0x3ffffff) << 2, 27) @@ -49,6 +50,20 @@ static inline u32 get_w_reg(struct pt_regs *regs, int re= g) return lower_32_bits(pt_regs_read_reg(regs, reg)); } =20 +static inline void update_lr(struct pt_regs *regs, long addr) +{ + int err =3D 0; + + if (user_mode(regs) && task_gcs_el0_enabled(current)) { + push_user_gcs(addr + 4, &err); + if (err) { + force_sig(SIGSEGV); + return; + } + } + procedure_link_pointer_set(regs, addr + 4); +} + static bool __kprobes check_cbz(u32 opcode, struct pt_regs *regs) { int xn =3D opcode & 0x1f; @@ -107,9 +122,8 @@ simulate_b_bl(u32 opcode, long addr, struct pt_regs *re= gs) { int disp =3D bbl_displacement(opcode); =20 - /* Link register is x30 */ if (opcode & (1 << 31)) - set_x_reg(regs, 30, addr + 4); + update_lr(regs, addr); =20 instruction_pointer_set(regs, addr + disp); } @@ -133,17 +147,26 @@ simulate_br_blr(u32 opcode, long addr, struct pt_regs= *regs) /* update pc first in case we're doing a "blr lr" */ instruction_pointer_set(regs, get_x_reg(regs, xn)); =20 - /* Link register is x30 */ if (((opcode >> 21) & 0x3) =3D=3D 1) - set_x_reg(regs, 30, addr + 4); + update_lr(regs, addr); } =20 void __kprobes simulate_ret(u32 opcode, long addr, struct pt_regs *regs) { - int xn =3D (opcode >> 5) & 0x1f; + u64 ret_addr; + int err =3D 0; + unsigned long lr =3D procedure_link_pointer(regs); =20 - instruction_pointer_set(regs, get_x_reg(regs, xn)); + if (user_mode(regs) && task_gcs_el0_enabled(current)) { + ret_addr =3D pop_user_gcs(&err); + if (err || ret_addr !=3D lr) { + force_sig(SIGSEGV); + return; + } + } + + instruction_pointer_set(regs, lr); } =20 void __kprobes --=20 2.50.1