Date: Wed, 9 Sep 2015 22:42:27 +0000 (UTC) From: John Baldwin <jhb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r287601 - head/tests/sys/kern Message-ID: <201509092242.t89MgRNX037295@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jhb Date: Wed Sep 9 22:42:26 2015 New Revision: 287601 URL: https://svnweb.freebsd.org/changeset/base/287601 Log: Add a test to verify that a traced process sees its original parent via getppid() after a debugger process that is not the parent has attached. Reviewed by: kib (earlier version) Differential Revision: https://reviews.freebsd.org/D3615 Modified: head/tests/sys/kern/ptrace_test.c Modified: head/tests/sys/kern/ptrace_test.c ============================================================================== --- head/tests/sys/kern/ptrace_test.c Wed Sep 9 21:18:10 2015 (r287600) +++ head/tests/sys/kern/ptrace_test.c Wed Sep 9 22:42:26 2015 (r287601) @@ -866,6 +866,92 @@ ATF_TC_BODY(ptrace__follow_fork_parent_d ATF_REQUIRE(errno == ECHILD); } +/* + * Verify that a child process does not see an unrelated debugger as its + * parent but sees its original parent process. + */ +ATF_TC_WITHOUT_HEAD(ptrace__getppid); +ATF_TC_BODY(ptrace__getppid, tc) +{ + pid_t child, debugger, ppid, wpid; + int cpipe[2], dpipe[2], status; + char c; + + ATF_REQUIRE(pipe(cpipe) == 0); + ATF_REQUIRE((child = fork()) != -1); + + if (child == 0) { + /* Child process. */ + close(cpipe[0]); + + /* Wait for parent to be ready. */ + CHILD_REQUIRE(read(cpipe[1], &c, sizeof(c)) == sizeof(c)); + + /* Report the parent PID to the parent. */ + ppid = getppid(); + CHILD_REQUIRE(write(cpipe[1], &ppid, sizeof(ppid)) == + sizeof(ppid)); + + _exit(1); + } + close(cpipe[1]); + + ATF_REQUIRE(pipe(dpipe) == 0); + ATF_REQUIRE((debugger = fork()) != -1); + + if (debugger == 0) { + /* Debugger process. */ + close(dpipe[0]); + + CHILD_REQUIRE(ptrace(PT_ATTACH, child, NULL, 0) != -1); + + wpid = waitpid(child, &status, 0); + CHILD_REQUIRE(wpid == child); + CHILD_REQUIRE(WIFSTOPPED(status)); + CHILD_REQUIRE(WSTOPSIG(status) == SIGSTOP); + + CHILD_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); + + /* Signal parent that debugger is attached. */ + CHILD_REQUIRE(write(dpipe[1], &c, sizeof(c)) == sizeof(c)); + + /* Wait for traced child to exit. */ + wpid = waitpid(child, &status, 0); + CHILD_REQUIRE(wpid == child); + CHILD_REQUIRE(WIFEXITED(status)); + CHILD_REQUIRE(WEXITSTATUS(status) == 1); + + _exit(0); + } + close(dpipe[1]); + + /* Parent process. */ + + /* Wait for the debugger to attach to the child. */ + ATF_REQUIRE(read(dpipe[0], &c, sizeof(c)) == sizeof(c)); + + /* Release the child. */ + ATF_REQUIRE(write(cpipe[0], &c, sizeof(c)) == sizeof(c)); + + /* Read the parent PID from the child. */ + ATF_REQUIRE(read(cpipe[0], &ppid, sizeof(ppid)) == sizeof(ppid)); + close(cpipe[0]); + + ATF_REQUIRE(ppid == getpid()); + + /* Wait for the debugger. */ + wpid = waitpid(debugger, &status, 0); + ATF_REQUIRE(wpid == debugger); + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE(WEXITSTATUS(status) == 0); + + /* The child process should now be ready. */ + wpid = waitpid(child, &status, WNOHANG); + ATF_REQUIRE(wpid == child); + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE(WEXITSTATUS(status) == 1); +} + ATF_TP_ADD_TCS(tp) { @@ -881,6 +967,7 @@ ATF_TP_ADD_TCS(tp) ptrace__follow_fork_child_detached_unrelated_debugger); ATF_TP_ADD_TC(tp, ptrace__follow_fork_parent_detached_unrelated_debugger); + ATF_TP_ADD_TC(tp, ptrace__getppid); return (atf_no_error()); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201509092242.t89MgRNX037295>