From owner-dev-commits-src-branches@freebsd.org Mon May 10 01:14:54 2021 Return-Path: Delivered-To: dev-commits-src-branches@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 67A00647F7A; Mon, 10 May 2021 01:14:54 +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 "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4FdjlK6rpSz4ZZw; Mon, 10 May 2021 01:14:53 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (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 did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 9BC3C1BE04; Mon, 10 May 2021 01:14:53 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 14A1Er67028714; Mon, 10 May 2021 01:14:53 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 14A1ErdR028713; Mon, 10 May 2021 01:14:53 GMT (envelope-from git) Date: Mon, 10 May 2021 01:14:53 GMT Message-Id: <202105100114.14A1ErdR028713@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Konstantin Belousov Subject: git: 4495cd6e7e50 - stable/13 - ptrace: do not allow for parallel ptrace requests MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 4495cd6e7e50e54515cc3d9b9faba7c6fb21042b Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-branches@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commits to the stable branches of the FreeBSD src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 May 2021 01:14:54 -0000 The branch stable/13 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=4495cd6e7e50e54515cc3d9b9faba7c6fb21042b commit 4495cd6e7e50e54515cc3d9b9faba7c6fb21042b Author: Konstantin Belousov AuthorDate: 2021-04-24 11:57:40 +0000 Commit: Konstantin Belousov CommitDate: 2021-05-10 01:02:47 +0000 ptrace: do not allow for parallel ptrace requests (cherry picked from commit 9ebf9100bad129a92961572ac862781d6c5681c7) --- sys/kern/sys_process.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- sys/sys/proc.h | 1 + 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index c93bfe15324c..e89fc6dff7e0 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -604,11 +604,18 @@ proc_set_traced(struct proc *p, bool stop) static int proc_can_ptrace(struct thread *td, struct proc *p) { + int error; + PROC_LOCK_ASSERT(p, MA_OWNED); if ((p->p_flag & P_WEXIT) != 0) return (ESRCH); + if ((error = p_cansee(td, p)) != 0) + return (error); + if ((error = p_candebug(td, p)) != 0) + return (error); + /* not being traced... */ if ((p->p_flag & P_TRACED) == 0) return (EPERM); @@ -640,10 +647,11 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) #ifdef COMPAT_FREEBSD32 int wrap32 = 0, safe = 0; #endif - bool proctree_locked; + bool proctree_locked, p2_req_set; curp = td->td_proc; proctree_locked = false; + p2_req_set = false; /* Lock proctree before locking the process. */ switch (req) { @@ -782,15 +790,47 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) /* FALLTHROUGH */ default: + /* + * Check for ptrace eligibility before waiting for + * holds to drain. + */ error = proc_can_ptrace(td, p); if (error != 0) goto fail; + /* + * Block parallel ptrace requests. Most important, do + * not allow other thread in debugger to continue the + * debuggee until coredump finished. + */ + while ((p->p_flag2 & P2_PTRACEREQ) != 0) { + if (proctree_locked) + sx_xunlock(&proctree_lock); + error = msleep(&p->p_flag2, &p->p_mtx, PPAUSE | PCATCH | + (proctree_locked ? PDROP : 0), "pptrace", 0); + if (proctree_locked) { + sx_xlock(&proctree_lock); + PROC_LOCK(p); + } + if (error == 0 && td2->td_proc != p) + error = ESRCH; + if (error == 0) + error = proc_can_ptrace(td, p); + if (error != 0) + goto fail; + } + /* Ok */ break; } - /* Keep this process around until we finish this request. */ + /* + * Keep this process around and request parallel ptrace() + * request to wait until we finish this request. + */ + MPASS((p->p_flag2 & P2_PTRACEREQ) == 0); + p->p_flag2 |= P2_PTRACEREQ; + p2_req_set = true; _PHOLD(p); /* @@ -1325,6 +1365,11 @@ out: /* Drop our hold on this process now that the request has completed. */ _PRELE(p); fail: + if (p2_req_set) { + if ((p->p_flag2 & P2_PTRACEREQ) != 0) + wakeup(&p->p_flag2); + p->p_flag2 &= ~P2_PTRACEREQ; + } PROC_UNLOCK(p); if (proctree_locked) sx_xunlock(&proctree_lock); diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 9de7be4628dd..0a779820fddc 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -817,6 +817,7 @@ struct proc { #define P2_STKGAP_DISABLE_EXEC 0x00001000 /* Stack gap disabled after exec */ #define P2_ITSTOPPED 0x00002000 +#define P2_PTRACEREQ 0x00004000 /* Active ptrace req */ /* Flags protected by proctree_lock, kept in p_treeflags. */ #define P_TREE_ORPHANED 0x00000001 /* Reparented, on orphan list */