From nobody Wed May 20 19:37:59 2026 X-Original-To: dev-commits-src-all@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 4gLMJm24mPz6fJWc for ; Wed, 20 May 2026 19:38:00 +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 4gLMJl4bfrz3V3S for ; Wed, 20 May 2026 19:37:59 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1779305879; 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=TvYgc1l+OMiuk2Gr26I/Gevn/SPhX7A8K0OnYS1fx7s=; b=Bfr4N7goImSZBvfTIM3N41/r0xwmHrBgRHSFRuCzriu+7pFfN4clqm/Aq16r5x1ZJ+3uFY 6wkFsptjascbrnkmvtyyDxNgxrgKb5Mthu8YUG3lh7YoezF6vewNs7MmviEgwbSNM56BJv grcdVX4E/oQYwwgxTdgM7nrwA8Gb++sYRUycJ7YEIUXcP2CW4z+ewUW80p/8jO7Rj9+0kU n6W1ZBAwRVF+/EFuUdD68LQQ53PsDbW3Y+aDlfnqqqvSz8ntNLX7w7OnK2+SOa3ugUyKTl HLbSpn61ixOSx2j8VRedzS6B3pkQUfN/zR9DB6upWjDQIXz4McKIyetv2quBuw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1779305879; a=rsa-sha256; cv=none; b=M1uj+DiHUSFkQnvW9DZ5wgqNVl9eaKE9+y1asVaM70KFbk1xIor5C9pciUJbgLDILLeIr6 B8JRt20ZQUGi9Gf9N14Bj2PPrvzJ/zweq7r5XBz5EAMwH6Q7YsTewm3RloFrByexm0YLto EXPFyf/jRcZwuSw961xszJstpxBHpwBIVSvdLsN5udTC+B4/N5lvQT81q4t6Ch9HPNyRIt mfLA+heLnOOHh+CJLBXvo2OGeMYQxnez9a1vpfcUwh+9dhRo2D+OrSdrTDauJQp6IRSAuJ SdJAl22A9x+f6cjS04loH1fJywUal2cjYAyedz4DnJl/9ClZgrl2a6jae3e2WA== 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=1779305879; 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=TvYgc1l+OMiuk2Gr26I/Gevn/SPhX7A8K0OnYS1fx7s=; b=Yu9bsBAhCyBghnCmhP1y38Riaj0pGk2YD4IIPO4gLJ+o/5GiL5+KIwtX9GrgOVqJzu+DTM d6ktZYYjM1n4vKA3eaOhiWkEpirJiPBU8hPPemZjxWHzGNv3aVgCW+cAONhXot7SDk75CO cx2WC62s4wqY/LqxuahftYj4ARQxxeUk3hsnR7V5OCA8IWpZaoV3fl5z2FL4cxl9QzegtH ypd17Z7OnBKXUVe7D5nmp2JbFWXZIqbZ5AgHzN0cZPjq9yQBROCQNpPMrXoYvPc5UxvaSN DIQ4X640zNIy3dj1Pb43ZEW9BS2QOqGA7NxuAC8G5K1hSN4lkACE0oFAIIYXXw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4gLMJl2zz0z1DhP for ; Wed, 20 May 2026 19:37:59 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 389d0 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Wed, 20 May 2026 19:37:59 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Mark Johnston Subject: git: fac902a3e039 - stable/14 - ptrace: Fix validation of PT_SC_REMOTE arguments List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@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/stable/14 X-Git-Reftype: branch X-Git-Commit: fac902a3e039b2a9ba432caa87ee18af96af3ff4 Auto-Submitted: auto-generated Date: Wed, 20 May 2026 19:37:59 +0000 Message-Id: <6a0e0d97.389d0.5a671e1f@gitrepo.freebsd.org> The branch stable/14 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=fac902a3e039b2a9ba432caa87ee18af96af3ff4 commit fac902a3e039b2a9ba432caa87ee18af96af3ff4 Author: Mark Johnston AuthorDate: 2026-05-12 17:32:17 +0000 Commit: Mark Johnston CommitDate: 2026-05-20 19:37:14 +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 5304436f4dd5..91361d680809 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -2692,23 +2692,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 b96e7d126b03..f5350524273b 100644 --- a/tests/sys/kern/ptrace_test.c +++ b/tests/sys/kern/ptrace_test.c @@ -4363,6 +4363,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. */ @@ -4387,35 +4406,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); } @@ -4658,6 +4704,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);