From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail.virtlab.unibo.it (mail.virtlab.unibo.it [130.136.161.50]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 44D1B137750 for ; Thu, 30 Jul 2026 07:48:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=130.136.161.50 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785397745; cv=none; b=b8b8GdcxtfaNbo5tVnFxiye+oX3j1bjO0kaetu6EZmJ+YDlw+USw8C/EMER1eE6ARqxfc+FafL2bnYxs3brMcV69c8HqxKV3a02CgV6Ie4yc8P/Ng388nnsKXDV0yI8WirsU2DXVLKsYfaDn9q5r1kRPLzRjS953/ESIbA4UpjE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785397745; c=relaxed/simple; bh=z6suj2bj5Mu7OLUDvfIjtYF6LfPvPQIVgiMUtCuInr4=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=QsAjIpZ+OWNnkd/6KTNPXnoQHOe30k58NKUfVqDkEBFDg3j3j1mWlSXVzbH1x3ZVB4gMSytbQk4e+htB5b14h33qjx6GArUB61NBlNMJd2oHeZg3dvvGsPY0ZWb0IsNRbTzMqL8nyL49qfWpe4AbRThzbnoh+w/HAH0UMTs2Mwg= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=cs.unibo.it; spf=pass smtp.mailfrom=cs.unibo.it; dkim=pass (1024-bit key) header.d=cs.unibo.it header.i=@cs.unibo.it header.b=McH3oBfC; arc=none smtp.client-ip=130.136.161.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=cs.unibo.it Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=cs.unibo.it Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=cs.unibo.it header.i=@cs.unibo.it header.b="McH3oBfC" Received: from cs.unibo.it (maddalena.cs.unibo.it [130.136.5.6]) by mail.virtlab.unibo.it (Postfix) with ESMTPSA id 009FF1C0095; Thu, 30 Jul 2026 09:39:44 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=cs.unibo.it; s=virtlab; t=1785397185; bh=z6suj2bj5Mu7OLUDvfIjtYF6LfPvPQIVgiMUtCuInr4=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=McH3oBfCqkzDvlPzrEmCoUsdHwGIgNujNo17BdZVNU5LD5EpvkHvUqN5D8qxZdfY9 8Gi+sQJOqEI2NMVxEOfND0LCXBNRTfOgJ+EHe2i0e9JEB+gikJkkR3t4ukbBKAndaC qiITAj0cu7uNva8ORP2X/75rnumUegyI+Hw5r36Y= Date: Thu, 30 Jul 2026 09:39:37 +0200 From: Renzo Davoli To: Michal =?iso-8859-1?Q?Such=E1nek?= Cc: linux-kernel@vger.kernel.org, Andrew Morton , Oleg Nesterov , Shuah Khan , Alexey Gladkov , Eugene Syromyatnikov , Davide Berardi , strace-devel@lists.strace.io, "Dmitry V . Levin" Subject: Re: [PATCH v5 0/2] PTRACE_SET_SYSCALL_INFO: add support for seccomp syscall skipping Message-ID: References: <20260709100949.94345-1-renzo@cs.unibo.it> 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=us-ascii Content-Disposition: inline In-Reply-To: Hi Michal, Thank you for pointing out the PowerPC issue. I spent some time tracing the syscall entry/exit path on a current kernel (git 0e35b9b6ec0ff + my syscall_skip patch) to understand where the return value is lost. The path I observed is the following: ptrace_set_syscall_info() syscall_set_nr(..., -1); syscall_set_return_value(..., 42); system_call_exception() r0 = syscall_enter_from_user_mode(...); if (r0 >= NR_syscalls) return -ENOSYS; interrupt_64.S bl system_call_exception bl syscall_exit_prepare syscall_exit_prepare(r3, regs, ...) regs->gpr[3] = r3; Initially I thought the return value from system_call_exception() was ignored, but the assembly passes the PPC64 ABI return register directly as the first argument to syscall_exit_prepare(). Consequently, the -ENOSYS returned by system_call_exception() becomes the value written back into regs->gpr[3]. To verify this, I added a few temporary pr_info() statements. Immediately after syscall_set_return_value(): ptrace: regs->gpr[3] = 42 and at the beginning of syscall_exit_prepare(): syscall_exit_prepare: r3 = -38 regs->gpr[3] = 42 where -38 is -ENOSYS. syscall_exit_prepare() then executes regs->gpr[3] = r3; so the value installed by syscall_set_return_value() is overwritten before returning to userspace. This reproduces exactly the behavior you described: on PowerPC, a return value preset before the syscall is skipped is not preserved through the architecture exit path. This also seems inconsistent with the generic contract documented in include/linux/entry-common.h, namely that if a skipped syscall already has a return value installed via syscall_set_return_value(), that value should be returned; otherwise the default result is -ENOSYS. The current PowerPC exit path always installs the default value. Given these observations, it seems that the ptrace patch is exposing an existing architectural issue rather than introducing a new one. Regarding possible solutions, I currently see two possible directions. * Introduce a pt_regs flag indicating that the final userspace return value has already been installed (as you suggested), so that syscall_exit_prepare() does not overwrite it. >From the PowerPC code path I investigated, this appears to be sufficient. The value installed by syscall_set_return_value() survives in regs->gpr[3] until syscall_exit_prepare(), where it is unconditionally replaced by the default -ENOSYS return value. In other words, the issue appears to be confined to the architecture-specific exit path. * Extend the generic syscall API (for example by introducing new helpers in asm/syscall.h or changing the semantics of the existing helpers) so that architectures can explicitly represent a final userspace return value. My impression is that Sven's proposal addresses a different problem, namely architectures where the live register state cannot safely hold the pending return value during syscall entry because it overlaps with the syscall number. On PowerPC, however, the value installed by syscall_set_return_value() is still present in regs->gpr[3] when syscall_exit_prepare() is entered, so the issue seems to be deciding whether the architecture should preserve that value or replace it with the default -ENOSYS. For this reason I am currently inclined towards the first approach for PowerPC, as it appears to be the minimal architecture-specific change required to restore the documented API contract. Does this match your understanding of the PowerPC exit path? If so, would you consider the flag approach the preferred direction for PowerPC? Thanks, renzo