From owner-svn-src-all@freebsd.org Mon Aug 5 20:15:47 2019 Return-Path: Delivered-To: svn-src-all@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 1B402AC3CC; Mon, 5 Aug 2019 20:15:47 +0000 (UTC) (envelope-from oshogbo@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) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 462TXy6zWcz49Js; Mon, 5 Aug 2019 20:15:46 +0000 (UTC) (envelope-from oshogbo@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id CD0412102E; Mon, 5 Aug 2019 20:15:46 +0000 (UTC) (envelope-from oshogbo@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x75KFkjD088669; Mon, 5 Aug 2019 20:15:46 GMT (envelope-from oshogbo@FreeBSD.org) Received: (from oshogbo@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x75KFk2R088667; Mon, 5 Aug 2019 20:15:46 GMT (envelope-from oshogbo@FreeBSD.org) Message-Id: <201908052015.x75KFk2R088667@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: oshogbo set sender to oshogbo@FreeBSD.org using -f From: Mariusz Zaborski Date: Mon, 5 Aug 2019 20:15:46 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r350612 - in head: sys/kern tests/sys/kern X-SVN-Group: head X-SVN-Commit-Author: oshogbo X-SVN-Commit-Paths: in head: sys/kern tests/sys/kern X-SVN-Commit-Revision: 350612 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 05 Aug 2019 20:15:47 -0000 Author: oshogbo Date: Mon Aug 5 20:15:46 2019 New Revision: 350612 URL: https://svnweb.freebsd.org/changeset/base/350612 Log: procdesc: fix reparenting when the debugger is attached The process is reparented to the debugger while it is attached. B B / ----> | A A D Every time when the process is reparented, it is added to the orphan list of the previous parent: A->orphan = B D->orphan = NULL When the A process will close the process descriptor to the B process, the B process will be reparented to the init process. B B - init | ----> A D A D A->orphan = B D->orphan = B In this scenario, the B process is in the orphan list of A and D. When the last process descriptor is closed instead of reparenting it to the reaper let it stay with the debugger process and set our previews parent to the reaper. Add test case for this situation. Notice that without this patch the kernel will crash with this test case: panic: orphan 0xfffff8000e990530 of 0xfffff8000e990000 has unexpected oppid 1 Reviewed by: markj, kib MFC after: 1 month Differential Revision: https://reviews.freebsd.org/D20361 Modified: head/sys/kern/sys_procdesc.c head/tests/sys/kern/ptrace_test.c Modified: head/sys/kern/sys_procdesc.c ============================================================================== --- head/sys/kern/sys_procdesc.c Mon Aug 5 20:11:57 2019 (r350611) +++ head/sys/kern/sys_procdesc.c Mon Aug 5 20:15:46 2019 (r350612) @@ -416,7 +416,13 @@ procdesc_close(struct file *fp, struct thread *td) * terminate with prejudice. */ p->p_sigparent = SIGCHLD; - proc_reparent(p, p->p_reaper, true); + if ((p->p_flag & P_TRACED) == 0) { + proc_reparent(p, p->p_reaper, true); + } else { + clear_orphan(p); + p->p_oppid = p->p_reaper->p_pid; + proc_add_orphan(p, p->p_reaper); + } if ((pd->pd_flags & PDF_DAEMON) == 0) kern_psignal(p, SIGKILL); PROC_UNLOCK(p); Modified: head/tests/sys/kern/ptrace_test.c ============================================================================== --- head/tests/sys/kern/ptrace_test.c Mon Aug 5 20:11:57 2019 (r350611) +++ head/tests/sys/kern/ptrace_test.c Mon Aug 5 20:15:46 2019 (r350612) @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -4075,6 +4076,60 @@ ATF_TC_BODY(ptrace__syscall_args, tc) ATF_REQUIRE(errno == ECHILD); } +/* + * Verify that when the process is traced that it isn't reparent + * to the init process when we close all process descriptors. + */ +ATF_TC(ptrace__proc_reparent); +ATF_TC_HEAD(ptrace__proc_reparent, tc) +{ + + atf_tc_set_md_var(tc, "timeout", "2"); +} +ATF_TC_BODY(ptrace__proc_reparent, tc) +{ + pid_t traced, debuger, wpid; + int pd, status; + + traced = pdfork(&pd, 0); + ATF_REQUIRE(traced >= 0); + if (traced == 0) { + raise(SIGSTOP); + exit(0); + } + ATF_REQUIRE(pd >= 0); + + debuger = fork(); + ATF_REQUIRE(debuger >= 0); + if (debuger == 0) { + /* The traced process is reparented to debuger. */ + ATF_REQUIRE(ptrace(PT_ATTACH, traced, 0, 0) == 0); + wpid = waitpid(traced, &status, 0); + ATF_REQUIRE(wpid == traced); + ATF_REQUIRE(WIFSTOPPED(status)); + ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); + ATF_REQUIRE(close(pd) == 0); + ATF_REQUIRE(ptrace(PT_DETACH, traced, (caddr_t)1, 0) == 0); + + /* We closed pd so we should not have any child. */ + wpid = wait(&status); + ATF_REQUIRE(wpid == -1); + ATF_REQUIRE(errno == ECHILD); + + exit(0); + } + + ATF_REQUIRE(close(pd) == 0); + wpid = waitpid(debuger, &status, 0); + ATF_REQUIRE(wpid == debuger); + ATF_REQUIRE(WEXITSTATUS(status) == 0); + + /* Check if we still have any child. */ + wpid = wait(&status); + ATF_REQUIRE(wpid == -1); + ATF_REQUIRE(errno == ECHILD); +} + ATF_TP_ADD_TCS(tp) { @@ -4137,6 +4192,7 @@ ATF_TP_ADD_TCS(tp) #endif ATF_TP_ADD_TC(tp, ptrace__PT_LWPINFO_stale_siginfo); ATF_TP_ADD_TC(tp, ptrace__syscall_args); + ATF_TP_ADD_TC(tp, ptrace__proc_reparent); return (atf_no_error()); }