From nobody Fri Oct 3 21:57:42 2025 Received: from smtps.ntu.edu.tw (smtps.ntu.edu.tw [140.112.2.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B9603264F85 for ; Sun, 24 Aug 2025 12:50:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=140.112.2.142 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756039804; cv=none; b=CMbyxMg6MzhOsBQ9IyH4stG3i7HtPx1iJlqxuUfByDV0z7pk4WUU7oqstwXpdZL59EJl0p2M5+aHTne91qXtSGnSNwrIzc6e5VDFyODI2p0g/skbKVTJSglEUW5rBMU+JKkpxjrTb0/U8gy+8gTeR2BmJ/+VUrMkOu/wgpZRRT4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756039804; c=relaxed/simple; bh=HUVpZAGjPziVrLOqrz+HXqAWKsDBSguYr4mqqUs+oW4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=efvXJ2C61M4UXLS4hUHN6PNll3biTLGAifk0d39otYAnMIoWw/8Na+wtkrgLB+Fxgl6t21HG0ZfQs8aCeXWHW/CDv1ImyF9e/+qpYCS2sa9w39U+4EUJwit27sg0oxV1xF7kzZPZbCfqhXWFUcJMyM4F3vhoQhxqtyNt9r5nalY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ntu.edu.tw; spf=pass smtp.mailfrom=ntu.edu.tw; arc=none smtp.client-ip=140.112.2.142 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ntu.edu.tw Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ntu.edu.tw Received: from x415ea.vlan11.wl120.cc.ntu.edu.tw (ip24-218.wifi.cc.ntu.edu.tw [140.112.24.218]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtps.ntu.edu.tw (Postfix) with ESMTPSA id 7502C2F104; Sun, 24 Aug 2025 20:43:50 +0800 (CST) From: b10902118 To: oleg@redhat.com, linux@armlinux.org.uk, catalin.marinas@arm.com, will@kernel.org Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, b10902118 Subject: [PATCH 1/3] arm64: ptrace: fix hw_break_set() by setting addr and ctrl together Date: Sun, 24 Aug 2025 20:43:15 +0800 Message-Id: <20250824124317.390795-2-b10902118@ntu.edu.tw> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250824124317.390795-1-b10902118@ntu.edu.tw> References: <20250824124317.390795-1-b10902118@ntu.edu.tw> 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" PTRACE_SETREGSET fails when setting a hardware breakpoint on a non-4-byte aligned address with a valid length to a 32-bit tracee. The length should be valid as long as the range started from the address is within one aligned 4 bytes. The cause is that hw_break_set() modifies a breakpoint's addr first and then ctrl. This calls modify_user_hw_breakpoint() twice, although once registering both suffices. The first modification causes errors because new addr and old ctrl can be an invalid combination at hw_breakpoint_arch_parse(). For example, when a user sets a hardware breakpoint with addr=3D0x2 and ctrl.len=3D1, hw_breakpoint_arch_parse() will first see addr=3D0x2 and ctrl.len=3D4 (the default) and return -EINVAL. On the other hand, if a user sets the same value to a breakpoint whose ctrl.len has previously been set to 1 or 2, it succeeds. The fix is to set addr and ctrl in one modify_user_hw_breakpoint(), effectively eliminating the discrepancy in validation. Signed-off-by: b10902118 --- arch/arm64/kernel/ptrace.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index 4b001121c..73c67f743 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -467,6 +467,32 @@ static int ptrace_hbp_set_addr(unsigned int note_type, return err; } =20 +/* Set the address and control together for non-compat ptrace */ +static int ptrace_hbp_set(unsigned int note_type, struct task_struct *tsk, + unsigned long idx, u64 addr, u32 uctrl) +{ + int err; + struct perf_event *bp; + struct perf_event_attr attr; + struct arch_hw_breakpoint_ctrl ctrl; + + bp =3D ptrace_hbp_get_initialised_bp(note_type, tsk, idx); + if (IS_ERR(bp)) { + err =3D PTR_ERR(bp); + return err; + } + + attr =3D bp->attr; + attr.bp_addr =3D addr; + + decode_ctrl_reg(uctrl, &ctrl); + err =3D ptrace_hbp_fill_attr_ctrl(note_type, ctrl, &attr); + if (err) + return err; + + return modify_user_hw_breakpoint(bp, &attr); +} + #define PTRACE_HBP_ADDR_SZ sizeof(u64) #define PTRACE_HBP_CTRL_SZ sizeof(u32) #define PTRACE_HBP_PAD_SZ sizeof(u32) @@ -524,9 +550,6 @@ static int hw_break_set(struct task_struct *target, return -EINVAL; ret =3D user_regset_copyin(&pos, &count, &kbuf, &ubuf, &addr, offset, offset + PTRACE_HBP_ADDR_SZ); - if (ret) - return ret; - ret =3D ptrace_hbp_set_addr(note_type, target, idx, addr); if (ret) return ret; offset +=3D PTRACE_HBP_ADDR_SZ; @@ -537,10 +560,11 @@ static int hw_break_set(struct task_struct *target, offset, offset + PTRACE_HBP_CTRL_SZ); if (ret) return ret; - ret =3D ptrace_hbp_set_ctrl(note_type, target, idx, ctrl); + offset +=3D PTRACE_HBP_CTRL_SZ; + + ret =3D ptrace_hbp_set(note_type, target, idx, addr, ctrl); if (ret) return ret; - offset +=3D PTRACE_HBP_CTRL_SZ; =20 user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, offset, offset + PTRACE_HBP_PAD_SZ); --=20 2.50.1 From nobody Fri Oct 3 21:57:42 2025 Received: from smtps.ntu.edu.tw (smtps.ntu.edu.tw [140.112.2.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 91D9D33F9 for ; Sun, 24 Aug 2025 12:44:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=140.112.2.142 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756039446; cv=none; b=BARyQJk4vrYu3OFzPADyYzg0Ec3+5EGZitCawbWBsQ8GJM4xFqmUZJrviYswAuX1MuyqWtBOeZ7p2ghnlBq2o5DWkHs5V4M3NPbf8fvwSqQ4XlPf70m7At9DynDygvDhPUVInhGNs22Xwjcp43Mcwm3RF2L3kw1AsU2Kq9Ql/sA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756039446; c=relaxed/simple; bh=UwxLhXbPOcuTU2WHpg6L/Wd9VldYmPQmXcjjJK/f6p8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=vD5Khq8916AImmP8uUxWbTxhOX3dh504Ur9RKmm5vP7xCRQcIfYW5LnfSNUBYFsjEU/qBYMF4EDGdm/frdSlLD7u/sl57Dszn46aBHsC9ZpEpK8a/ypb6xDGLpn9XFbt6k5gx3tLN0znT7BngQxHo0TRH/sN1fHxH3A47n8SaPI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ntu.edu.tw; spf=pass smtp.mailfrom=ntu.edu.tw; arc=none smtp.client-ip=140.112.2.142 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ntu.edu.tw Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ntu.edu.tw Received: from x415ea.vlan11.wl120.cc.ntu.edu.tw (ip24-218.wifi.cc.ntu.edu.tw [140.112.24.218]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtps.ntu.edu.tw (Postfix) with ESMTPSA id 75BB22E6C1; Sun, 24 Aug 2025 20:43:56 +0800 (CST) From: b10902118 To: oleg@redhat.com, linux@armlinux.org.uk, catalin.marinas@arm.com, will@kernel.org Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, b10902118 Subject: [PATCH 2/3] arm64: ptrace: minimize default bp_len for hw breakpoints to pass check Date: Sun, 24 Aug 2025 20:43:16 +0800 Message-Id: <20250824124317.390795-3-b10902118@ntu.edu.tw> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250824124317.390795-1-b10902118@ntu.edu.tw> References: <20250824124317.390795-1-b10902118@ntu.edu.tw> 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" PTRACE_SETHBPREGS fails when setting a hardware breakpoint on a non-4-byte aligned address with a valid length to a 32-bit tracee. The length should be valid as long as the range started from the address is within one aligned 4 bytes. The cause is that compat_ptrace_hbp_set() can only modify either addr or ctrl of a breakpoint per call, but always checks alignment in hw_breakpoint_arch_parse(). If a breakpoint has ctrl.len=3D4 (the default), then users cannot set the addr to a non-4-byte aligned address. Likewise, if the addr was previously set unaligned, users cannot set ctrl.len to 4. This patch mitigates the issue by minimizing the default bp_len, so that any possibly valid address can pass the check with it. However, it does not solve misaligned addr/len in modifying existing breakpoints; further work may be needed to remove or relax the alignment check. Signed-off-by: b10902118 --- arch/arm64/kernel/ptrace.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index 73c67f743..70c9acd94 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -288,14 +288,25 @@ static struct perf_event *ptrace_hbp_create(unsigned = int note_type, { struct perf_event *bp; struct perf_event_attr attr; - int err, type; + int err, type, min_len; =20 + /* + * min_len ensures any possibly valid address can pass alignment + * validation with it. + * This is for compat mode, in which addr and ctrl can only be set + * one after one with SETHBPREGS. If addr is set first, ctrl will + * remain as initial value. + */ switch (note_type) { case NT_ARM_HW_BREAK: type =3D HW_BREAKPOINT_X; + min_len =3D (tsk && is_compat_thread(task_thread_info(tsk))) ? + HW_BREAKPOINT_LEN_2 : + HW_BREAKPOINT_LEN_4; break; case NT_ARM_HW_WATCH: type =3D HW_BREAKPOINT_RW; + min_len =3D HW_BREAKPOINT_LEN_1; break; default: return ERR_PTR(-EINVAL); @@ -308,7 +319,7 @@ static struct perf_event *ptrace_hbp_create(unsigned in= t note_type, * (i.e. values that will pass validation). */ attr.bp_addr =3D 0; - attr.bp_len =3D HW_BREAKPOINT_LEN_4; + attr.bp_len =3D min_len; attr.bp_type =3D type; attr.disabled =3D 1; =20 --=20 2.50.1 From nobody Fri Oct 3 21:57:42 2025 Received: from smtps.ntu.edu.tw (smtps.ntu.edu.tw [140.112.2.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 91DCE2B2D7 for ; Sun, 24 Aug 2025 12:44:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=140.112.2.142 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756039445; cv=none; b=EFhkwqaqmXaKm4jU1gQ1ymKWSrLDilHbGMevgWhuKhH4Wnmw0oTIs9WFv3Ib2WI6vfMwWSK5I+7e8TgxLbx8A4hea8tMXCE2p5QyhXwUAN24rCHb9Tluuv5cqte9hyk2UO7RnsBp4BwRQCUd/YKtAfQrrq10Y9ldT94wRXwmfQI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756039445; c=relaxed/simple; bh=EGrSHTapPc7vwzx+kgXnQiuYgGdua0vWOKBlIYZjWGs=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=d7mEtz6Asf3bROtwn+fXsmdKPZBgHHO8jhYQDVHAHV2noMtNCZw+tfB4zWVmbwQnrZUWBpmIArCX0QYc0JE0OKG/i8x1QWoMhx3zPv260SdxFf+3anlMLTVGHiA3iUU5K35L/+rarKqsXCydL2GV1wYUQKTAZixHkbxnKyvy1Zo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ntu.edu.tw; spf=pass smtp.mailfrom=ntu.edu.tw; arc=none smtp.client-ip=140.112.2.142 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ntu.edu.tw Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ntu.edu.tw Received: from x415ea.vlan11.wl120.cc.ntu.edu.tw (ip24-218.wifi.cc.ntu.edu.tw [140.112.24.218]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtps.ntu.edu.tw (Postfix) with ESMTPSA id DED282E6C3; Sun, 24 Aug 2025 20:44:01 +0800 (CST) From: b10902118 To: oleg@redhat.com, linux@armlinux.org.uk, catalin.marinas@arm.com, will@kernel.org Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, b10902118 Subject: [PATCH 3/3] ARM: ptrace: minimize default bp_len for hw breakpoints to pass check Date: Sun, 24 Aug 2025 20:43:17 +0800 Message-Id: <20250824124317.390795-4-b10902118@ntu.edu.tw> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250824124317.390795-1-b10902118@ntu.edu.tw> References: <20250824124317.390795-1-b10902118@ntu.edu.tw> 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" PTRACE_SETHBPREGS fails when setting a hardware breakpoint on a non-4-byte aligned address with a valid length to a 32-bit tracee. The length should be valid as long as the range started from the address is within one aligned 4 bytes. The cause is that ptrace_sethbpregs() can only modify either addr or ctrl of a breakpoint per call, but always checks alignment in hw_breakpoint_arch_parse(). If a breakpoint has ctrl.len=3D4 (the default), then users cannot set the addr to a non-4-byte aligned address. Likewise, if the addr was previously set unaligned, users cannot set ctrl.len to 4. This patch mitigates the issue by minimizing the default bp_len, so that any possibly valid address can pass the check with it. However, it does not solve misaligned addr/len in modifying existing breakpoints; further work may be needed to remove or relax the alignment check. Signed-off-by: b10902118 --- arch/arm/kernel/ptrace.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 7951b2c06..920cf77d1 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -415,12 +415,26 @@ static u32 ptrace_get_hbp_resource_info(void) static struct perf_event *ptrace_hbp_create(struct task_struct *tsk, int t= ype) { struct perf_event_attr attr; + int min_len; + + /* + * min_len ensures any possibly valid address can pass alignment + * validation with it. + * In PTRACE_SETHBPREGS, addr and ctrl can only be set one after one. If + * addr is set first, ctrl will remain as initial value. + */ + if (type =3D=3D HW_BREAKPOINT_X) + min_len =3D (tsk && is_compat_thread(task_thread_info(tsk))) ? + HW_BREAKPOINT_LEN_2 : + HW_BREAKPOINT_LEN_4; + else // watchpoint + min_len =3D HW_BREAKPOINT_LEN_1; =20 ptrace_breakpoint_init(&attr); =20 /* Initialise fields to sane defaults. */ attr.bp_addr =3D 0; - attr.bp_len =3D HW_BREAKPOINT_LEN_4; + attr.bp_len =3D min_len; attr.bp_type =3D type; attr.disabled =3D 1; =20 --=20 2.50.1