From nobody Sat Jul 25 22:31:38 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 15D0517C203; Sun, 12 Jul 2026 21:25:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783891522; cv=none; b=FcNt77GolSz3z32K+ZtuaQn0ApXHtxvxwVZOlr4/njAbUN5ei/v2dcIE43Z9MrTBRVrEUdUdTnKHBObF2nEk4xjgYmukKngmTUKeavlwJIABBdbkA5C20E9k0a2UvoQ8GkaD0X1DMlJDW6mZGF/higEu6VQuAKjDiMIBbQUTzec= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783891522; c=relaxed/simple; bh=xiQKERVLXlhv9R6+U6VqsicxLm/lazckEJoktsa0NN4=; h=Date:Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=G6CevikakztsYZIbxYJZRfmk5Uv7Su8VzIgdHtoJtO+fer8QMnlCLrxWh4RLY54LDYKYjE+8uYKqUg8+qseIu+0XiJgNgb/+S9MzWTXmeO27rdvt5Viti3axjsPR19Pmo8BmAal0Yr5HXEUJjaGbqFlLEvv9OibpY3tarOyULW8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MeR46zuk; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="MeR46zuk" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 18F6D1F000E9; Sun, 12 Jul 2026 21:25:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1783891520; bh=rQWZ8aJgOncbggueFnURmOMnwueR0POClkrjreehrRg=; h=Date:From:To:Cc:Subject:References; b=MeR46zuk5udFu+6sitLOWkIvT2D1oWkOX3LZL64wi0Wue7pZZoj92eYrZyCHwL6re LtNulxNY9Xfv0bKY212BxpjPh6OQuqFHmkUTpzE0rrlt4QxqdZebZE1KDm4nZUEhMp ZsMDsH3MWEuTn7puKH/TLmpD43nwClU5g498mnR/jpAbyFSVn7gqOikHCa1XfLi/OZ AxtODzhSPI53UIID1Fh9XQID2bGnMTk5jyR9XlEl7In4QJRq8W/lVDvsymIMGYh57F hQWVHq+yBg4dJ6sMKRBey0cUbgn5O4cPuwCH4e7tb62pq2ioZJr+suHGx6CzXWo5pw 5bSB+97HCh1VA== Date: Sun, 12 Jul 2026 23:25:17 +0200 Message-ID: <20260712141346.576865340@kernel.org> User-Agent: quilt/0.69 From: Thomas Gleixner To: LKML Cc: =?UTF-8?q?Michal=20Such=C3=A1nek?= , Michael Ellerman , Shrikanth Hegde , linuxppc-dev@lists.ozlabs.org, Huacai Chen , loongarch@lists.linux.dev, Paul Walmsley , Palmer Dabbelt , linux-riscv@lists.infradead.org, Sven Schnelle , linux-s390@vger.kernel.org, x86@kernel.org, Mark Rutland , Jinjie Ruan , Magnus Lindholm , "Mukesh Kumar Chaurasiya (IBM)" , Jonathan Corbet , Radu Rendec Subject: [patch 1/4] entry: Rework syscall_audit_enter() References: <20260712134433.549076055@kernel.org> 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" Move it out of line and let it reread the syscall number on it's own. That makes the low level entry code denser and allows to move the reread to the call site of syscall_trace_enter() once the tracer is fixed up. Signed-off-by: Thomas Gleixner Reviewed-by: Jinjie Ruan Reviewed-by: Radu Rendec Tested-by: Michal Such=C3=A1nek --- include/linux/entry-common.h | 14 +++----------- kernel/entry/syscall-common.c | 10 ++++++++++ 2 files changed, 13 insertions(+), 11 deletions(-) --- a/include/linux/entry-common.h +++ b/include/linux/entry-common.h @@ -60,16 +60,7 @@ static __always_inline bool arch_ptrace_ =20 long trace_syscall_enter(struct pt_regs *regs, long syscall); void trace_syscall_exit(struct pt_regs *regs, long ret); - -static inline void syscall_enter_audit(struct pt_regs *regs, long syscall) -{ - if (unlikely(audit_context())) { - unsigned long args[6]; - - syscall_get_arguments(current, regs, args); - audit_syscall_entry(syscall, args[0], args[1], args[2], args[3]); - } -} +void syscall_enter_audit(struct pt_regs *regs); =20 static __always_inline long syscall_trace_enter(struct pt_regs *regs, unsi= gned long work, long syscall) @@ -111,7 +102,8 @@ static __always_inline long syscall_trac if (unlikely(work & SYSCALL_WORK_SYSCALL_TRACEPOINT)) syscall =3D trace_syscall_enter(regs, syscall); =20 - syscall_enter_audit(regs, syscall); + if (unlikely(audit_context())) + syscall_enter_audit(regs); =20 return syscall; } --- a/kernel/entry/syscall-common.c +++ b/kernel/entry/syscall-common.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 =20 +#include #include =20 #define CREATE_TRACE_POINTS @@ -21,3 +22,12 @@ void trace_syscall_exit(struct pt_regs * { trace_sys_exit(regs, ret); } + +void syscall_enter_audit(struct pt_regs *regs) +{ + long syscall =3D syscall_get_nr(current, regs); + unsigned long args[6]; + + syscall_get_arguments(current, regs, args); + __audit_syscall_entry(syscall, args[0], args[1], args[2], args[3]); +} From nobody Sat Jul 25 22:31:38 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 B7DB617C203; Sun, 12 Jul 2026 21:25:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783891526; cv=none; b=DziCGML0ckC1Gc1eswJdDZIv4sOUQ08CVz+xp8WCYf7QhKPZEjWd6PFOxKKR7r/dDhXgSsqSCdsx9h5jouIFnGvS2MLZ9Po5ATivPS8MIDU6amKrM7b3hNozFOJMHLbCyJzeKa+xI2R7LwTM7+Yb6YxufXWG+Qo2YOK4dfoTLFg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783891526; c=relaxed/simple; bh=vnUndRc7gzdHX7DknVwrYPY2as0EUIrJp2S28xgLaT8=; h=Date:Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=QBMGZzpb37CJ2M41Dud94IJ67bGny5JJWpVV6QhXflVEHNGCJm1L6/XPJdBBNLE1keiwredzesI1sHX+JtKw00+KhjxH11d9q9k85gk6m6474Y7OMx/wo5l3VAUie4iGIpVDbkEN2nJ//gJGA9l4CgaPoGvUGlgGMlncYzcNXMk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mzeCuuT0; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="mzeCuuT0" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0BF891F000E9; Sun, 12 Jul 2026 21:25:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1783891525; bh=2JItWlUO0RtFZwJ9AedXkVw8o5YILdxQ5hx8qr2Nb5s=; h=Date:From:To:Cc:Subject:References; b=mzeCuuT0JQcjq0ffdG1mMOXvwVg7uBygi4ikhxj2XYUNlmMfzmfn3U2nH5Q/s2tYT hE6So6oMIRH9zZo8P+kLDM1SHxS9ep4XeX4OI3bWj66SvgdPaw44aKEwaw1MYINh0H 4zCSmz9lTSmItEjpfX/V5TRcJOf34STaoyRjMoXNl0u96NUZtWitt5VWhcdZN+gCWy 1VFaBHkKtdt0C3blUBtUpl6PbzJYJ53qjO+yF+0U6mYoA2Nbt0/kmPWWjLEgxJP/cY oOTjW6RijF7rhFsJnEwV9x1TsJubt24VulGi6dqcPQSyG1yrH+hb9EUlxjDaCvPx9L hy+Ix8nbOcXZQ== Date: Sun, 12 Jul 2026 23:25:22 +0200 Message-ID: <20260712141346.639115923@kernel.org> User-Agent: quilt/0.69 From: Thomas Gleixner To: LKML Cc: =?UTF-8?q?Michal=20Such=C3=A1nek?= , Michael Ellerman , Shrikanth Hegde , linuxppc-dev@lists.ozlabs.org, Huacai Chen , loongarch@lists.linux.dev, Paul Walmsley , Palmer Dabbelt , linux-riscv@lists.infradead.org, Sven Schnelle , linux-s390@vger.kernel.org, x86@kernel.org, Mark Rutland , Jinjie Ruan , Magnus Lindholm , "Mukesh Kumar Chaurasiya (IBM)" , Jonathan Corbet , Radu Rendec Subject: [patch 2/4] entry: Rework trace_syscall_enter() References: <20260712134433.549076055@kernel.org> 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" Reread the syscall number from pt_regs and stop returning the eventually modified syscall number. That moves the reread to the end of the syscall_trace_enter() and prepares for moving it to the call site. No functional change. Signed-off-by: Thomas Gleixner Reviewed-by: Jinjie Ruan Reviewed-by: Radu Rendec Tested-by: Michal Such=C3=A1nek --- include/linux/entry-common.h | 10 ++++------ kernel/entry/syscall-common.c | 9 ++------- 2 files changed, 6 insertions(+), 13 deletions(-) --- a/include/linux/entry-common.h +++ b/include/linux/entry-common.h @@ -58,7 +58,7 @@ static __always_inline bool arch_ptrace_ } #endif =20 -long trace_syscall_enter(struct pt_regs *regs, long syscall); +void trace_syscall_enter(struct pt_regs *regs); void trace_syscall_exit(struct pt_regs *regs, long ret); void syscall_enter_audit(struct pt_regs *regs); =20 @@ -96,16 +96,14 @@ static __always_inline long syscall_trac return -1L; } =20 - /* Either of the above might have changed the syscall number */ - syscall =3D syscall_get_nr(current, regs); - if (unlikely(work & SYSCALL_WORK_SYSCALL_TRACEPOINT)) - syscall =3D trace_syscall_enter(regs, syscall); + trace_syscall_enter(regs); =20 if (unlikely(audit_context())) syscall_enter_audit(regs); =20 - return syscall; + /* Either of the above might have changed the syscall number */ + return syscall_get_nr(current, regs); } =20 /** --- a/kernel/entry/syscall-common.c +++ b/kernel/entry/syscall-common.c @@ -8,14 +8,9 @@ =20 /* Out of line to prevent tracepoint code duplication */ =20 -long trace_syscall_enter(struct pt_regs *regs, long syscall) +void trace_syscall_enter(struct pt_regs *regs) { - trace_sys_enter(regs, syscall); - /* - * Probes or BPF hooks in the tracepoint may have changed the - * system call number. Reread it. - */ - return syscall_get_nr(current, regs); + trace_sys_enter(regs, syscall_get_nr(current, regs)); } =20 void trace_syscall_exit(struct pt_regs *regs, long ret) From nobody Sat Jul 25 22:31:38 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 A4D303769EF; Sun, 12 Jul 2026 21:25:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783891531; cv=none; b=hWE8rvVx9NZKgLioubjQQxCIv1shT4zK3NvTIg9vSmRCRa+sQBwapEzTzwyNsfvnujii6U/gwq0O2fDXzZkMBktLglXrspV+q3WrXx11Yqgm6/USGcyI3v2L/AXjXZ+O6VOWSfK208h/Tcx60D3d2QhzyQOm7SCJzgDex+zxtsQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783891531; c=relaxed/simple; bh=C7H4U6sMO4YkOH5pYiIoQ+0TycDVOUBpFLeQIr+ccoo=; h=Date:Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=FvGNrbUIkMT9idBADJplqWsbSaCO80ysf+feQXegryVXTBI1AjoIU6xBopzaBYEyzTYhvE/JuyYVj9eEZ0hJWxI4kdp4aK8BVdILlkM4rvNs+zri5glZtxGa5aS/6ACSpDXYrKrSICVgGr6IX/PblbuyBSQ707OG3DdwwiTJlU8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RLFHFdpF; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="RLFHFdpF" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BE9691F000E9; Sun, 12 Jul 2026 21:25:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1783891530; bh=3dgiu8TI4TCoeEn0bEpVdfOeeBtaQ/CqpKNHZxWnkT0=; h=Date:From:To:Cc:Subject:References; b=RLFHFdpFXUTSZm/YBrtnuBzx0Yh8fHlGCVPyr2M8hm65643btsbKADLAv6wpykm33 Eg0cUgOEJOfikXRmAG51l2v8MPBdeAm4aMIOyJ/i6di5f7CALzJWxWHCoNxcD6S0ah FX4lwJrcKFzpB2M5EgU1/ICA5lBHJxPds5h1Jxb+KnbSYzz3UD+j9I76Mfca2WnMrL l+97Kjp5ak82rCbAcIT3mOGGkVYr59ROgtUEPIgjxvkwzQUd/3aKLG8Jh+dmHXGXKQ EXN1m1qE2cZM4dUpd34jLSEE6VEv5KNYMkU6dEdFEGOJLIsBjxZdcBSNxnjfoamDuS GhGN8JsoJebPw== Date: Sun, 12 Jul 2026 23:25:27 +0200 Message-ID: <20260712141346.699072205@kernel.org> User-Agent: quilt/0.69 From: Thomas Gleixner To: LKML Cc: =?UTF-8?q?Michal=20Such=C3=A1nek?= , Michael Ellerman , Shrikanth Hegde , linuxppc-dev@lists.ozlabs.org, Huacai Chen , loongarch@lists.linux.dev, Paul Walmsley , Palmer Dabbelt , linux-riscv@lists.infradead.org, Sven Schnelle , linux-s390@vger.kernel.org, x86@kernel.org, Mark Rutland , Jinjie Ruan , Magnus Lindholm , "Mukesh Kumar Chaurasiya (IBM)" , Jonathan Corbet , Radu Rendec Subject: [patch 3/4] entry: Make return type of syscall_trace_enter() bool References: <20260712134433.549076055@kernel.org> 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" From: Thomas Gleixner This prepares for changing the return types of syscall_enter_from_user_mode[_work]() to bool, which in turn separates the decision of invoking the syscall from the syscall number, which might have been changed in the call by ptrace, seccomp, tracing. Signed-off-by: Thomas Gleixner Reviewed-by: Jinjie Ruan Reviewed-by: Radu Rendec Tested-by: Michal Such=C3=A1nek --- include/linux/entry-common.h | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) --- a/include/linux/entry-common.h +++ b/include/linux/entry-common.h @@ -72,7 +72,7 @@ static __always_inline long syscall_trac */ if (work & SYSCALL_WORK_SYSCALL_USER_DISPATCH) { if (syscall_user_dispatch(regs)) - return -1L; + return false; } =20 /* @@ -87,13 +87,13 @@ static __always_inline long syscall_trac if (work & (SYSCALL_WORK_SYSCALL_TRACE | SYSCALL_WORK_SYSCALL_EMU)) { if (!arch_ptrace_report_syscall_permit_entry(regs) || (work & SYSCALL_WORK_SYSCALL_EMU)) - return -1L; + return false; } =20 /* Do seccomp after ptrace, to catch any tracer changes. */ if (work & SYSCALL_WORK_SECCOMP) { if (!__seccomp_permit_syscall()) - return -1L; + return false; } =20 if (unlikely(work & SYSCALL_WORK_SYSCALL_TRACEPOINT)) @@ -102,8 +102,7 @@ static __always_inline long syscall_trac if (unlikely(audit_context())) syscall_enter_audit(regs); =20 - /* Either of the above might have changed the syscall number */ - return syscall_get_nr(current, regs); + return true; } =20 /** @@ -133,8 +132,13 @@ static __always_inline long syscall_ente { unsigned long work =3D READ_ONCE(current_thread_info()->syscall_work); =20 - if (work & SYSCALL_WORK_ENTER) - syscall =3D syscall_trace_enter(regs, work, syscall); + if (work & SYSCALL_WORK_ENTER) { + if (!syscall_trace_enter(regs, work, syscall)) + return -1L; + + /* Reread the syscall number as it might have been modified */ + syscall =3D syscall_get_nr(current, regs); + } =20 return syscall; } From nobody Sat Jul 25 22:31:38 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 72E46376BC5; Sun, 12 Jul 2026 21:25:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783891537; cv=none; b=N4I/qP+F9iEY7WNvG5ale+qURsqxRkLeXqDNzQjBvdeof/8OBrAnc5K9B8m3jSpPVTNyM9eZc0FEHUetzt20rsev+Ac9FDnOVwJSkjtF/6R7nug06F8XlOsjY42ZI23OGsu9EKZnsK59D+2CVh1UYNdE+9KHN9XjtV+gNKRJSl8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783891537; c=relaxed/simple; bh=Asvgx0JwKVJjV3R2bafHRGMczJnqFdg3KQc8+hTMs60=; h=Date:Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=QYMxlRtJSMNzSbc9EdI3i01B44o0g6UE532AkvGxQldK+I+EUv0DrRm5I4Csp2BY5htdwgGddIvQir2+9HhgVyQVVYvFimvJKWxb8lTdalcOKxpRxZDIj/vyfTStEBjzWJNl+RxoJwd7j9bC5oEQvp3jNat3dcViaMxv4xeTsjA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ULDEH+ZE; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ULDEH+ZE" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AB3151F000E9; Sun, 12 Jul 2026 21:25:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1783891535; bh=jivMYDxXpiwA3cut01lRa4UxTZlEBG7iWpRHqtzKrVo=; h=Date:From:To:Cc:Subject:References; b=ULDEH+ZELnoOzYAgeamKbQ7TvwpfrRxh/SEaWxPjoP2LXUfXVZA2Z5lgq4Kkkb8HF MEiWqScTs29ODMGgZkhCTFFbfvJijQ05Hzk8KtYWMcQU/rhc+YYvZPmnl2weGWiS7B ueZoJ2Fc1WtT8gBjPyvsKG+hW67vgwLhtXyg60df/BKAZf9rNspotBIHHjP01sD2CS 1snRVzCxKITqJ+SS8Gks2PodDMgcoWpTvkB2qTlnxnPpagRssivRSyQ2hb31CNPKiX MvEeRAfdIhntqZk81AW1QegO4k33z3e0I4gTHLVMEKFwrpPLgvn0noMxwhQ5t49SAc lfwF4QijEBRGw== Date: Sun, 12 Jul 2026 23:25:32 +0200 Message-ID: <20260712141346.772209074@kernel.org> User-Agent: quilt/0.69 From: Thomas Gleixner To: LKML Cc: =?UTF-8?q?Michal=20Such=C3=A1nek?= , Michael Ellerman , Shrikanth Hegde , linuxppc-dev@lists.ozlabs.org, Huacai Chen , loongarch@lists.linux.dev, Paul Walmsley , Palmer Dabbelt , linux-riscv@lists.infradead.org, Sven Schnelle , linux-s390@vger.kernel.org, x86@kernel.org, Mark Rutland , Jinjie Ruan , Magnus Lindholm , "Mukesh Kumar Chaurasiya (IBM)" , Jonathan Corbet , Radu Rendec Subject: [patch 4/4] entry, treewide: Make syscall_enter_from_user_mode[_work]() indicate syscall execution References: <20260712134433.549076055@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The return values of syscall_enter_from_user_mode[_work]() are non-intuitive. Both functions return the syscall number which should be invoked by the architecture specific syscall entry code. The returned number can be: - the unmodified syscall number which was handed in by the caller - a modified syscall number (ptrace, seccomp, trace/probe/bpf) That has an additional twist. If the return value is -1L then the caller is not allowed to modify the return value as that indicates that the modifying entity requests to abort the syscall and set the return value already. That can obviously not be differentiated from a syscall which handed in -1 as syscall number. The most trivial way to deal with that is: set_return_value(regs, -ENOSYS); nr =3D syscall_enter_from_user_mode(regs, nr); if (valid(nr)) handle_syscall(regs, nr); That's what LOONGARCH, RISCV, and X86 do. But PowerPC and S390 do not preset the return value, so when user space hands in -1 and there is nothing setting the return value in the entry work code, then the syscall is skipped but the return value is whatever random data has been in the return value register. Change the return values of syscall_enter_from_user_mode[_work]() to boolean and return false, when either ptrace or seccomp request to skip the syscall. If they return true, update the syscall number as it might have been changed. That results in slightly different behaviour of the architectures versus tracing. If the syscall tracepoint has probe/BPF attached, those might set the syscall number to -1 and also set the return value. PowerPC and S390 will then overwrite that value with -ENOSYS. The other architectures will just ignore it like any other invalid syscall and use the modified one. Originally-by: Michal Such=C3=A1nek Signed-off-by: Thomas Gleixner Reviewed-by: Radu Rendec Tested-by: Michal Such=C3=A1nek --- V2: Change the return logic so Power and S390 can insist on being special. --- Documentation/core-api/entry.rst | 45 ++++++++++++++++++++++++++++++----= ----- arch/loongarch/kernel/syscall.c | 14 ++++++------ arch/powerpc/kernel/syscall.c | 3 +- arch/riscv/kernel/traps.c | 11 ++++----- arch/s390/kernel/syscall.c | 7 ++++-- arch/x86/entry/syscall_32.c | 25 ++++++++++----------- arch/x86/entry/syscall_64.c | 12 +++++----- include/linux/entry-common.h | 32 +++++++++++++-------------- 8 files changed, 88 insertions(+), 61 deletions(-) --- a/Documentation/core-api/entry.rst +++ b/Documentation/core-api/entry.rst @@ -58,26 +58,51 @@ state transitions must run with interrup Syscalls -------- =20 -Syscall-entry code starts in assembly code and calls out into low-level C = code -after establishing low-level architecture-specific state and stack frames.= This -low-level C code must not be instrumented. A typical syscall handling func= tion -invoked from low-level assembly code looks like this: +Syscall-entry code starts in assembly code and calls out into low-level C +code after establishing low-level architecture-specific state and stack +frames. This low-level C code must not be instrumented. The recommended +syscall handling function invoked from low-level assembly code looks like +this: =20 .. code-block:: c =20 - noinstr void syscall(struct pt_regs *regs, int nr) + noinstr void syscall(struct pt_regs *regs, long nr) { arch_syscall_enter(regs); - nr =3D syscall_enter_from_user_mode_randomize_stack(regs, nr); + result_reg(regs) =3D -ENOSYS; + if (syscall_enter_from_user_mode_randomize_stack(regs, &nr)) { + instrumentation_begin(); + if (valid(nr) + result_reg(regs) =3D invoke_syscall(regs, nr); + instrumentation_end(); + } + syscall_exit_to_user_mode(regs); + } =20 - instrumentation_begin(); - if (!invoke_syscall(regs, nr) && nr !=3D -1) - result_reg(regs) =3D __sys_ni_syscall(regs); - instrumentation_end(); +This is the most resilent variant as it has always a guaranteed valid +return code. The alternative variant is: + +.. code-block:: c =20 + noinstr void syscall(struct pt_regs *regs, long nr) + { + arch_syscall_enter(regs); + if (syscall_enter_from_user_mode_randomize_stack(regs, &nr)) { + instrumentation_begin(); + if (valid(nr) + result_reg(regs) =3D invoke_syscall(regs, nr); + else + result_reg(regs) =3D -ENOSYS; + instrumentation_end(); + } syscall_exit_to_user_mode(regs); } =20 +That works for most situations except when a probe/BPF attached to the +syscall tracepoint sets an invalid syscall number e.g. -1 and also modifies +the result register. So this variant will obviously overwrite the modified +result with -ENOSYS. + syscall_enter_from_user_mode_randomize_stack() first invokes enter_from_user_mode_randomize_stack() which establishes state in the following order: --- a/arch/loongarch/kernel/syscall.c +++ b/arch/loongarch/kernel/syscall.c @@ -57,8 +57,8 @@ typedef long (*sys_call_fn)(unsigned lon =20 void noinstr __no_stack_protector do_syscall(struct pt_regs *regs) { - unsigned long nr; sys_call_fn syscall_fn; + unsigned long nr; =20 nr =3D regs->regs[11]; /* Set for syscall restarting */ @@ -69,12 +69,12 @@ void noinstr __no_stack_protector do_sys regs->orig_a0 =3D regs->regs[4]; regs->regs[4] =3D -ENOSYS; =20 - nr =3D syscall_enter_from_user_mode_randomize_stack(regs, nr); - - if (nr < NR_syscalls) { - syscall_fn =3D sys_call_table[array_index_nospec(nr, NR_syscalls)]; - regs->regs[4] =3D syscall_fn(regs->orig_a0, regs->regs[5], regs->regs[6], - regs->regs[7], regs->regs[8], regs->regs[9]); + if (likely(syscall_enter_from_user_mode_randomize_stack(regs, &nr))) { + if (nr < NR_syscalls) { + syscall_fn =3D sys_call_table[array_index_nospec(nr, NR_syscalls)]; + regs->regs[4] =3D syscall_fn(regs->orig_a0, regs->regs[5], regs->regs[6= ], + regs->regs[7], regs->regs[8], regs->regs[9]); + } } =20 syscall_exit_to_user_mode(regs); --- a/arch/powerpc/kernel/syscall.c +++ b/arch/powerpc/kernel/syscall.c @@ -18,7 +18,8 @@ notrace long system_call_exception(struc long ret; syscall_fn f; =20 - r0 =3D syscall_enter_from_user_mode_randomize_stack(regs, r0); + if (unlikely(!syscall_enter_from_user_mode_randomize_stack(regs, &r0))) + return syscall_get_error(current, regs); =20 if (unlikely(r0 >=3D NR_syscalls)) { if (unlikely(trap_is_unsupported_scv(regs))) { --- a/arch/riscv/kernel/traps.c +++ b/arch/riscv/kernel/traps.c @@ -332,13 +332,12 @@ void do_trap_ecall_u(struct pt_regs *reg =20 riscv_v_vstate_discard(regs); =20 - syscall =3D syscall_enter_from_user_mode_randomize_stack(regs, syscall); - - if (syscall >=3D 0 && syscall < NR_syscalls) { - syscall =3D array_index_nospec(syscall, NR_syscalls); - syscall_handler(regs, syscall); + if (likely(syscall_enter_from_user_mode_randomize_stack(regs, &syscall))= ) { + if (syscall >=3D 0 && syscall < NR_syscalls) { + syscall =3D array_index_nospec(syscall, NR_syscalls); + syscall_handler(regs, syscall); + } } - syscall_exit_to_user_mode(regs); } else { irqentry_state_t state =3D irqentry_nmi_enter(regs); --- a/arch/s390/kernel/syscall.c +++ b/arch/s390/kernel/syscall.c @@ -96,6 +96,7 @@ SYSCALL_DEFINE0(ni_syscall) void noinstr __do_syscall(struct pt_regs *regs, int per_trap) { unsigned long nr; + bool permit; =20 enter_from_user_mode_randomize_stack(regs); =20 @@ -121,7 +122,9 @@ void noinstr __do_syscall(struct pt_regs regs->psw.addr =3D current->restart_block.arch_data; current->restart_block.arch_data =3D 1; } - nr =3D syscall_enter_from_user_mode_work(regs, nr); + + permit =3D syscall_enter_from_user_mode_work(regs, &nr); + /* * In the s390 ptrace ABI, both the syscall number and the return value * use gpr2. However, userspace puts the syscall number either in the @@ -129,7 +132,7 @@ void noinstr __do_syscall(struct pt_regs * work, the ptrace code sets PIF_SYSCALL_RET_SET, which is checked here * and if set, the syscall will be skipped. */ - if (unlikely(test_and_clear_pt_regs_flag(regs, PIF_SYSCALL_RET_SET))) + if (unlikely(test_and_clear_pt_regs_flag(regs, PIF_SYSCALL_RET_SET) || !p= ermit)) goto out; regs->gprs[2] =3D -ENOSYS; if (likely(nr < NR_syscalls)) { --- a/arch/x86/entry/syscall_32.c +++ b/arch/x86/entry/syscall_32.c @@ -161,8 +161,9 @@ static __always_inline bool int80_is_ext nr =3D syscall_32_enter(regs); =20 local_irq_enable(); - nr =3D syscall_enter_from_user_mode_work(regs, nr); - do_syscall_32_irqs_on(regs, nr); + + if (likely(syscall_enter_from_user_mode_work(regs, &nr))) + do_syscall_32_irqs_on(regs, nr); =20 instrumentation_end(); syscall_exit_to_user_mode(regs); @@ -223,8 +224,8 @@ DEFINE_FREDENTRY_RAW(int80_emulation) nr =3D syscall_32_enter(regs); =20 local_irq_enable(); - nr =3D syscall_enter_from_user_mode_work(regs, nr); - do_syscall_32_irqs_on(regs, nr); + if (likely(syscall_enter_from_user_mode_work(regs, &nr))) + do_syscall_32_irqs_on(regs, nr); =20 instrumentation_end(); syscall_exit_to_user_mode(regs); @@ -243,13 +244,13 @@ DEFINE_FREDENTRY_RAW(int80_emulation) * orig_ax, the int return value truncates it. This matches * the semantics of syscall_get_nr(). */ - nr =3D syscall_enter_from_user_mode_randomize_stack(regs, nr); - - instrumentation_begin(); + if (likely(syscall_enter_from_user_mode_randomize_stack(regs, &nr))) { + instrumentation_begin(); =20 - do_syscall_32_irqs_on(regs, nr); + do_syscall_32_irqs_on(regs, nr); =20 - instrumentation_end(); + instrumentation_end(); + } syscall_exit_to_user_mode(regs); } #endif /* !CONFIG_IA32_EMULATION */ @@ -286,10 +287,8 @@ static noinstr bool __do_fast_syscall_32 return false; } =20 - nr =3D syscall_enter_from_user_mode_work(regs, nr); - - /* Now this is just like a normal syscall. */ - do_syscall_32_irqs_on(regs, nr); + if (likely(syscall_enter_from_user_mode_work(regs, &nr))) + do_syscall_32_irqs_on(regs, nr); =20 instrumentation_end(); syscall_exit_to_user_mode(regs); --- a/arch/x86/entry/syscall_64.c +++ b/arch/x86/entry/syscall_64.c @@ -78,14 +78,14 @@ static __always_inline void do_syscall_x /* Returns true to return using SYSRET, or false to use IRET */ __visible noinstr bool do_syscall_64(struct pt_regs *regs, long nr) { - nr =3D syscall_enter_from_user_mode_randomize_stack(regs, nr); + if (likely(syscall_enter_from_user_mode_randomize_stack(regs, &nr))) { + instrumentation_begin(); =20 - instrumentation_begin(); + if (!do_syscall_x64(regs, nr)) + do_syscall_x32(regs, nr); =20 - if (!do_syscall_x64(regs, nr)) - do_syscall_x32(regs, nr); - - instrumentation_end(); + instrumentation_end(); + } syscall_exit_to_user_mode(regs); =20 /* --- a/include/linux/entry-common.h +++ b/include/linux/entry-common.h @@ -111,16 +111,15 @@ static __always_inline long syscall_trac * @regs: Pointer to currents pt_regs * @syscall: The syscall number * - * Invoked from architecture specific syscall entry code with interrupts - * enabled after invoking enter_from_user_mode(), enabling interrupts and - * extra architecture specific work. + * Invoked from architecture specific syscall entry code with interrupts e= nabled + * after invoking enter_from_user_mode(), enabling interrupts and extra + * architecture specific work with the syscall return value preset to -ENO= SYS. * - * Returns: The original or a modified syscall number + * Returns: True if the syscall should be invoked, False otherwise. * - * If the returned syscall number is -1 then the syscall should be - * skipped. In this case the caller may invoke syscall_set_error() or - * syscall_set_return_value() first. If neither of those are called and -1 - * is returned, then the syscall will fail with ENOSYS. + * If the return value is false, the caller must skip the syscall and leav= e the + * syscall return value unmodified as it might have been set by one of the= entry + * work functions. * * It handles the following work items: * @@ -128,19 +127,20 @@ static __always_inline long syscall_trac * ptrace_report_syscall_permit_entry(), __seccomp_permit_syscall(), t= race_sys_enter() * 2) Invocation of audit_syscall_entry() */ -static __always_inline long syscall_enter_from_user_mode_work(struct pt_re= gs *regs, long syscall) +static __always_inline bool syscall_enter_from_user_mode_work(struct pt_re= gs *regs, long *syscall) { unsigned long work =3D READ_ONCE(current_thread_info()->syscall_work); =20 - if (work & SYSCALL_WORK_ENTER) { - if (!syscall_trace_enter(regs, work, syscall)) - return -1L; + if (!(work & SYSCALL_WORK_ENTER)) + return true; =20 - /* Reread the syscall number as it might have been modified */ - syscall =3D syscall_get_nr(current, regs); - } + if (unlikely(!syscall_trace_enter(regs, work, *syscall))) + return false; =20 - return syscall; + /* Reread the syscall number as it might have been modified */ + *syscall =3D syscall_get_nr(current, regs); + + return true; } =20 /**