Module Name:    src
Committed By:   kamil
Date:           Tue Nov  8 14:49:04 UTC 2016

Modified Files:
        src/tests/kernel: t_ptrace.c

Log Message:
Add new test attach_chroot in t_ptrace

Assert that a debugger cannot trace another process unless the process's
root directory is at or below the tracing process's root.

Sponsored by <The NetBSD Foundation>.


To generate a diff of this commit:
cvs rdiff -u -r1.14 -r1.15 src/tests/kernel/t_ptrace.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/tests/kernel/t_ptrace.c
diff -u src/tests/kernel/t_ptrace.c:1.14 src/tests/kernel/t_ptrace.c:1.15
--- src/tests/kernel/t_ptrace.c:1.14	Tue Nov  8 11:21:41 2016
+++ src/tests/kernel/t_ptrace.c	Tue Nov  8 14:49:04 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: t_ptrace.c,v 1.14 2016/11/08 11:21:41 kamil Exp $	*/
+/*	$NetBSD: t_ptrace.c,v 1.15 2016/11/08 14:49:04 kamil Exp $	*/
 
 /*-
  * Copyright (c) 2016 The NetBSD Foundation, Inc.
@@ -27,12 +27,12 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: t_ptrace.c,v 1.14 2016/11/08 11:21:41 kamil Exp $");
+__RCSID("$NetBSD: t_ptrace.c,v 1.15 2016/11/08 14:49:04 kamil Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/ptrace.h>
-#include <sys/wait.h>
+#include <sys/stat.h>
 #include <err.h>
 #include <errno.h>
 #include <unistd.h>
@@ -104,11 +104,76 @@ ATF_TC_BODY(attach_self, tc)
 	ATF_REQUIRE_ERRNO(EINVAL, ptrace(PT_ATTACH, getpid(), NULL, 0) == -1);
 }
 
+ATF_TC(attach_chroot);
+ATF_TC_HEAD(attach_chroot, tc)
+{
+	atf_tc_set_md_var(tc, "descr",
+	    "Assert that a debugger cannot trace another process unless the "
+	    "process's root directory is at or below the tracing process's "
+	    "root");
+
+	atf_tc_set_md_var(tc, "require.user", "root");
+}                    
+
+ATF_TC_BODY(attach_chroot, tc)
+{
+	char buf[PATH_MAX];
+	pid_t child;
+	int fds_toparent[2], fds_fromparent[2];
+	int rv;
+	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
+
+	(void)memset(buf, '\0', sizeof(buf));
+	ATF_REQUIRE(getcwd(buf, sizeof(buf)) != NULL);
+	(void)strlcat(buf, "/dir", sizeof(buf));
+
+	ATF_REQUIRE(mkdir(buf, 0500) == 0);
+	ATF_REQUIRE(chdir(buf) == 0);
+
+	ATF_REQUIRE(pipe(fds_toparent) == 0);
+	ATF_REQUIRE(pipe(fds_fromparent) == 0);
+	child = atf_utils_fork();
+	if (child == 0) {
+		FORKEE_ASSERT(close(fds_toparent[0]) == 0);
+		FORKEE_ASSERT(close(fds_fromparent[1]) == 0);
+
+		FORKEE_ASSERT(chroot(buf) == 0);
+
+		rv = write(fds_toparent[1], &msg, sizeof(msg));
+		FORKEE_ASSERTX(rv == sizeof(msg));
+
+		ATF_REQUIRE_ERRNO(EPERM,
+			ptrace(PT_ATTACH, getppid(), NULL, 0) == -1);
+
+		rv = read(fds_fromparent[0], &msg, sizeof(msg));
+		FORKEE_ASSERTX(rv == sizeof(msg));
+
+		_exit(0);
+	}
+	ATF_REQUIRE(close(fds_toparent[1]) == 0);
+	ATF_REQUIRE(close(fds_fromparent[0]) == 0);
+
+	printf("Waiting for chrooting of the child PID %d", child);
+	rv = read(fds_toparent[0], &msg, sizeof(msg));
+	ATF_REQUIRE(rv == sizeof(msg)); 
+
+	printf("Child is ready, it will try to PT_ATTACH to parent\n");
+	rv = write(fds_fromparent[1], &msg, sizeof(msg));
+	ATF_REQUIRE(rv == sizeof(msg));
+
+        printf("fds_fromparent is no longer needed - close it\n");
+        ATF_REQUIRE(close(fds_fromparent[1]) == 0);
+
+        printf("fds_toparent is no longer needed - close it\n");
+        ATF_REQUIRE(close(fds_toparent[0]) == 0);
+}
+
 ATF_TP_ADD_TCS(tp)
 {
 	ATF_TP_ADD_TC(tp, attach_pid0);
 	ATF_TP_ADD_TC(tp, attach_pid1);
 	ATF_TP_ADD_TC(tp, attach_self);
+	ATF_TP_ADD_TC(tp, attach_chroot);
 
 	return atf_no_error();
 }

Reply via email to