From nobody Wed May 20 19:35:47 2026 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4gLMGD4d5Fz6fHxl for ; Wed, 20 May 2026 19:35:48 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R13" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4gLMGC74lBz3QMK for ; Wed, 20 May 2026 19:35:47 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1779305748; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=43p/QhU0n+KP0q/R30U3UEaHKWaLICzSJyhlrVvpa/o=; b=gm87uFn+e4C5CeCzI5F6Wry3W8b/Lou+n0xSsIdf+Yu3716n7JP7iWcgGcvteuJNlRSeCg PYisNs7yXIv2lnGTZX3Z5fndvW/sXC2KR11jcYa6T9+2oUocHRh921pBuq21b2ekZSCnHH XUVcZYzfgML0immXrIdTnRQdTGT2ueA3bHhMWgbqCfkMph6zF8KkuQu/P4Z7i2Fn7uNQzg eD7pBt1dhZiGZOs+R+ykBgmhpcJsCQomx/bqL9LqDU45vFQsSllUYzWztJxJEJnTeB/TWO jnP+wwflGcfnYDkwymQUXXztVndpGPC0GD9EgfWeVojP+02VuaXIvQm27cmu8Q== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1779305748; a=rsa-sha256; cv=none; b=LVYa32DE9xoaUCRdrR0zvNlT9UC9f02bQ98f1+zbZ6mAHyWMilpdx6P1ACoa7AQMi0a2bW BzPXjE6avZYOtQ54nUYcQEb1CiPekDZmd1I5/op3id14XrwIfQy43+GMhfSZ+RDnxY3UQ+ KuZax7EsT/xu7mB7zPZKEuXwyNaul6EbDIYTcMWNDlv2/cMiRCMmA366IgC3pDdMzHrjDI DK11tx8jWmfal5qTm8vJGAj3iyF3IH9nOk8dsC3S7ZABAFzWOpsTbxZ4GP2r4d3sF4CdHS cZ5YqQSpI/GaT/d+WkekGJVMj4IOrmV2lRY6wXYuwipRI2gjDpzBpdfsUaUZvQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1779305748; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=43p/QhU0n+KP0q/R30U3UEaHKWaLICzSJyhlrVvpa/o=; b=aDOu26uAaIsOd3Ns4YUTphW7HjjdChn8arzjEsMzgKd5Q/5anT7Q8Sp9LC0q7VzeGHhxji 6vsoqGvEnIfEvIg/CbChXS021b5MMM2BvlEQ8NSpKw4n+gekVx4XNU0XtpuU4Fk6UcoATM 4S5lgJ6f8V9TuXuaB7aVDrVtCQyFGyZeK6qln22F+EPQTlfjjSh937qIquf4MAZrOfN5zz uFHx1ZFqPhtvAfmZgs2AziLqC2cHNSAMZD4hiyq/76qvGCBNiWAXxrH1dm6N2KUJbidXU+ ajZs6RZudRkNcgrYiTE6NmorLZbt3r1561yDTxIemLkL3Cuf2S//0AVsEg/w8A== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4gLMGC6SJSz1DrX for ; Wed, 20 May 2026 19:35:47 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 38a34 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Wed, 20 May 2026 19:35:47 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Mark Johnston Subject: git: dea055a0e86f - main - ptrace: Fix validation of PT_SC_REMOTE arguments List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: dea055a0e86fc279a51439b695461b3eda94ad0b Auto-Submitted: auto-generated Date: Wed, 20 May 2026 19:35:47 +0000 Message-Id: <6a0e0d13.38a34.236fe67e@gitrepo.freebsd.org> The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=dea055a0e86fc279a51439b695461b3eda94ad0b commit dea055a0e86fc279a51439b695461b3eda94ad0b Author: Mark Johnston AuthorDate: 2026-05-12 17:32:17 +0000 Commit: Mark Johnston CommitDate: 2026-05-20 19:34:50 +0000 ptrace: Fix validation of PT_SC_REMOTE arguments - Fix an off-by-one in the system call number check. A value of SYS_MAXSYSCALL was permitted. - Validate the system call number after we've dealt with syscall(2)/__syscall(2), since they pass the syscall number as an argument. - When the syscall number is for syscall(2) or __syscall(2), we must make sure that nargs > 0 to avoid an underflow when shifting arguments down. Add regression tests. Approved by: so Security: FreeBSD-SA-26:21.ptrace Security: CVE-2026-45253 Fixes: 140ceb5d956b ("ptrace(2): add PT_SC_REMOTE remote syscall request") Reported by: Yuxiang Yang, Yizhou Zhao, Ao Wang, Xuewei Feng, Qi Li, and Ke Xu from Tsinghua University using GLM-5.1 from Z.ai Reviewed by: kib, emaste Differential Revision: https://reviews.freebsd.org/D56978 --- sys/kern/kern_sig.c | 17 +++++---- tests/sys/kern/ptrace_test.c | 85 ++++++++++++++++++++++++++++++++++---------- 2 files changed, 76 insertions(+), 26 deletions(-) diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index a55f3c761449..9be7c82ee98b 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -2679,23 +2679,26 @@ ptrace_syscallreq(struct thread *td, struct proc *p, struct sysentvec *sv; struct sysent *se; register_t rv_saved[2]; + unsigned int sc; int error, nerror; - int sc; bool audited, sy_thr_static; - sv = p->p_sysent; - if (sv->sv_table == NULL || sv->sv_size < tsr->ts_sa.code) { - tsr->ts_ret.sr_error = ENOSYS; - return; - } - sc = tsr->ts_sa.code; if (sc == SYS_syscall || sc == SYS___syscall) { + if (tsr->ts_nargs == 0) { + tsr->ts_ret.sr_error = EINVAL; + return; + } sc = tsr->ts_sa.args[0]; memmove(&tsr->ts_sa.args[0], &tsr->ts_sa.args[1], sizeof(register_t) * (tsr->ts_nargs - 1)); } + sv = p->p_sysent; + if (sv->sv_table == NULL || sc >= sv->sv_size) { + tsr->ts_ret.sr_error = ENOSYS; + return; + } tsr->ts_sa.callp = se = &sv->sv_table[sc]; VM_CNT_INC(v_syscall); diff --git a/tests/sys/kern/ptrace_test.c b/tests/sys/kern/ptrace_test.c index fee0bd2ffa38..c1a5d226e990 100644 --- a/tests/sys/kern/ptrace_test.c +++ b/tests/sys/kern/ptrace_test.c @@ -4362,6 +4362,25 @@ ATF_TC_BODY(ptrace__procdesc_reparent_wait_child, tc) REQUIRE_EQ(close(pd), 0); } +static void +pt_sc_remote(pid_t pid, struct ptrace_sc_remote *pscr, int error, + syscallarg_t ret) +{ + pid_t wpid; + int status; + + ATF_REQUIRE(ptrace(PT_SC_REMOTE, pid, (caddr_t)pscr, sizeof(*pscr)) != + -1); + ATF_REQUIRE_EQ(pscr->pscr_ret.sr_error, error); + if (error == 0) + ATF_REQUIRE_EQ(pscr->pscr_ret.sr_retval[0], ret); + + wpid = waitpid(pid, &status, 0); + REQUIRE_EQ(wpid, pid); + ATF_REQUIRE(WIFSTOPPED(status)); + REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); +} + /* * Try using PT_SC_REMOTE to get the PID of a traced child process. */ @@ -4386,35 +4405,62 @@ ATF_TC_BODY(ptrace__PT_SC_REMOTE_getpid, tc) pscr.pscr_syscall = SYS_getpid; pscr.pscr_nargs = 0; pscr.pscr_args = NULL; - ATF_REQUIRE(ptrace(PT_SC_REMOTE, fpid, (caddr_t)&pscr, sizeof(pscr)) != - -1); - ATF_REQUIRE_MSG(pscr.pscr_ret.sr_error == 0, - "remote getpid failed with error %d", pscr.pscr_ret.sr_error); - ATF_REQUIRE_MSG(pscr.pscr_ret.sr_retval[0] == fpid, - "unexpected return value %jd instead of %d", - (intmax_t)pscr.pscr_ret.sr_retval[0], fpid); - - wpid = waitpid(fpid, &status, 0); - REQUIRE_EQ(wpid, fpid); - ATF_REQUIRE(WIFSTOPPED(status)); - REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); + pt_sc_remote(fpid, &pscr, 0, fpid); pscr.pscr_syscall = SYS_getppid; pscr.pscr_nargs = 0; pscr.pscr_args = NULL; - ATF_REQUIRE(ptrace(PT_SC_REMOTE, fpid, (caddr_t)&pscr, sizeof(pscr)) != - -1); - ATF_REQUIRE_MSG(pscr.pscr_ret.sr_error == 0, - "remote getppid failed with error %d", pscr.pscr_ret.sr_error); - ATF_REQUIRE_MSG(pscr.pscr_ret.sr_retval[0] == getpid(), - "unexpected return value %jd instead of %d", - (intmax_t)pscr.pscr_ret.sr_retval[0], fpid); + pt_sc_remote(fpid, &pscr, 0, getpid()); + + ATF_REQUIRE(ptrace(PT_DETACH, fpid, (caddr_t)1, 0) != -1); +} + +ATF_TC_WITHOUT_HEAD(ptrace__PT_SC_REMOTE_syscall_validation); +ATF_TC_BODY(ptrace__PT_SC_REMOTE_syscall_validation, tc) +{ + struct ptrace_sc_remote pscr; + quad_t code; + int status; + pid_t fpid, wpid; + + code = SYS_MAXSYSCALL; + + ATF_REQUIRE((fpid = fork()) != -1); + if (fpid == 0) { + trace_me(); + exit(0); + } wpid = waitpid(fpid, &status, 0); REQUIRE_EQ(wpid, fpid); ATF_REQUIRE(WIFSTOPPED(status)); REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); + pscr.pscr_syscall = SYS_MAXSYSCALL; + pscr.pscr_nargs = 0; + pscr.pscr_args = NULL; + pt_sc_remote(fpid, &pscr, ENOSYS, 0); + + pscr.pscr_syscall = SYS_syscall; + pscr.pscr_nargs = 0; + pscr.pscr_args = NULL; + pt_sc_remote(fpid, &pscr, EINVAL, 0); + + pscr.pscr_syscall = SYS_syscall; + pscr.pscr_nargs = 1; + pscr.pscr_args = (syscallarg_t *)&code; + pt_sc_remote(fpid, &pscr, ENOSYS, 0); + + pscr.pscr_syscall = SYS___syscall; + pscr.pscr_nargs = 0; + pscr.pscr_args = NULL; + pt_sc_remote(fpid, &pscr, EINVAL, 0); + + pscr.pscr_syscall = SYS___syscall; + pscr.pscr_nargs = 1; + pscr.pscr_args = (syscallarg_t *)&code; + pt_sc_remote(fpid, &pscr, ENOSYS, 0); + ATF_REQUIRE(ptrace(PT_DETACH, fpid, (caddr_t)1, 0) != -1); } @@ -4657,6 +4703,7 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, ptrace__procdesc_wait_child); ATF_TP_ADD_TC(tp, ptrace__procdesc_reparent_wait_child); ATF_TP_ADD_TC(tp, ptrace__PT_SC_REMOTE_getpid); + ATF_TP_ADD_TC(tp, ptrace__PT_SC_REMOTE_syscall_validation); ATF_TP_ADD_TC(tp, ptrace__reap_kill_stopped); ATF_TP_ADD_TC(tp, ptrace__PT_ATTACH_no_EINTR); ATF_TP_ADD_TC(tp, ptrace__PT_DETACH_continued);