PERFORCE change 163769 for review

Robert Watson rwatson at FreeBSD.org
Mon Jun 8 08:58:55 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=163769

Change 163769 by rwatson at rwatson_freebsd_capabilities on 2009/06/08 08:58:00

	Clean up cap_exec by adding various utility functions, etc.

Affected files ...

.. //depot/projects/trustedbsd/capabilities/src/tools/cap/cap_exec/cap_exec.c#5 edit

Differences ...

==== //depot/projects/trustedbsd/capabilities/src/tools/cap/cap_exec/cap_exec.c#5 (text+ko) ====

@@ -65,16 +65,39 @@
 #define	BIN_CAPS	(CAP_SEEK | CAP_FSTAT | CAP_FSTATFS | CAP_READ | \
 			    CAP_FEXECVE | CAP_MMAP | CAP_MAPEXEC)
 
+static void
+cap_limitfd(int fd, cap_rights_t rights)
+{
+	int fd_new;
+
+	fd_new = cap_new(fd, rights);
+	if (fd_new < 0)
+		err(-1, "cap_new");
+	if (fd_new != fd) {
+		if (dup2(fd_new, fd) < 0)
+			err(-1, "dup2");
+		close(fd_new);
+	}
+}
+
+static int
+cap_open_limit(const char *path, int flags, cap_rights_t rights)
+{
+	int fd;
+
+	fd = open(path, flags);
+	if (fd < 0)
+		err(-1, "open: %s", path);
+	cap_limitfd(fd, rights);
+	return (fd);
+}
+
 int
 main(int argc, char *argv[])
 {
-	int fd_exec, fd_libc, fd_new;
-	int fd_stdin, fd_stdout, fd_stderr, fd_procdesc;
+	int fd_exec, fd_ldso, fd_libc, fd_procdesc;
 	char *env_caplibindex;
 	struct pollfd pollfd;
-#ifdef LDSO_MODE
-	int fd_ldso;
-#endif
 	pid_t pid;
 
 	if (argc < 2)
@@ -85,104 +108,44 @@
 		err(-1, "pdfork");
 	if (pid == 0) {
 		/*
-		 * Open files by name before entering capability mode.  Flag
-		 * for close when fexecve(2) runs.
-		 */
-		fd_exec = open(argv[1], O_RDONLY);
-		if (fd_exec < 0)
-			err(-1, "open: %s", argv[1]);
-#ifdef LDSO_MODE
-		if (fd_exec != 3)
-			errx(-1, "fd_exec not fd 3");
-		fd_ldso = open(LD_ELF_CAP_SO, O_RDONLY);
-		if (fd_ldso < 0)
-			err(-1, "open: %s", LD_ELF_CAP_SO);
-		fd_new = cap_new(fd_ldso, BIN_CAPS);
-		if (fd_new < 0)
-			err(-1, "cap_new");
-		if (dup2(fd_new, fd_ldso) < 0)
-			err(-1, "dup2");
-		close(fd_new);
-		if (fcntl(fd_ldso, F_SETFD, FD_CLOEXEC) < 0)
-			err(-1, "fcntl FD_CLOEXEC");
-
-		fd_libc = open(LIBPATH LIBC_SO, O_RDONLY);
-		if (fd_libc < 0)
-			err(-1, "open: %s", LIBPATH LIBC_SO);
-		fd_new = cap_new(fd_libc, BIN_CAPS);
-		if (fd_new < 0)
-			err(-1, "cap_new");
-		if (dup2(fd_new, fd_libc) < 0)
-			err(-1, "dup2");
-		close(fd_new);
-#else
-		if (fcntl(fd_exec, F_SETFD, FD_CLOEXEC) < 0)
-			err(-1, "fcntl FD_CLOEXEC");
-#endif
-
-		/*
-		 * Global namespaces no longer required, enter capability
-		 * mode.
-		 */
-		if (cap_enter() < 0)
-			err(-1, "cap_enter");
-
-		/*
 		 * Set up stdin, stdout, and stderr by wrapping the existing
 		 * file descriptors in constrained capabilities.
 		 */
-		fd_stdin = cap_new(STDIN_FILENO, STDIN_CAPS);
-		if (fd_stdin < 0)
-			err(-1, "cap_new");
-		if (dup2(fd_stdin, STDIN_FILENO) < 0)
-			err(-1, "dup2");
-		close(fd_stdin);
-
-		fd_stdout = cap_new(STDOUT_FILENO, STDOUT_CAPS);
-		if (fd_stdout < 0)
-			err(-1, "cap_new");
-		if (dup2(fd_stdout, STDOUT_FILENO) < 0)
-			err(-1, "dup2");
-		close(fd_stdout);
-
-		fd_stderr = cap_new(STDERR_FILENO, STDERR_CAPS);
-		if (fd_stderr < 0)
-			err(-1, "cap_new");
-		if (dup2(fd_stderr, STDERR_FILENO) < 0)
-			err(-1, "dup2");
-		close(fd_stderr);
+		cap_limitfd(STDIN_FILENO, STDIN_CAPS);
+		cap_limitfd(STDOUT_FILENO, STDOUT_CAPS);
+		cap_limitfd(STDERR_FILENO, STDERR_CAPS);
 
 		/*
-		 * Set up environmental variable so that the runtime linker
-		 * can access libc in a sandbox.
+		 * Open and configure the binary, ELF interpreter, and libc.
+		 * The rtld-elf-cap runtime requires the binary to be passed
+		 * as fd 3, so verify that's what we got.
 		 */
-#ifdef LDSO_MODE
+		fd_exec = cap_open_limit(argv[1], O_RDONLY, BIN_CAPS);
+		if (fd_exec != 3)
+			err(-1, "cap_open_limit(%s) returned fd %d", argv[1],
+			    fd_exec);
+		fd_ldso = cap_open_limit(LD_ELF_CAP_SO, O_RDONLY, BIN_CAPS);
+		if (fcntl(fd_ldso, F_SETFD, FD_CLOEXEC) < 0)
+			err(-1, "fcntl FD_CLOEXEC");
+		fd_libc = cap_open_limit(LIBPATH LIBC_SO, O_RDONLY, BIN_CAPS);
 		if (asprintf(&env_caplibindex, "%d:%s", fd_libc, LIBC_SO) ==
 		    -1)
 			err(-1, "asprintf");
-		printf("caplibindex: %s\n", env_caplibindex);
 		setenv("LD_CAPLIBINDEX", env_caplibindex, 1);
-#endif
 
 		/*
-		 * Perhaps a closeall() or something to clear any remaining
-		 * file descriptors here?
+		 * Global namespaces no longer required, enter capability
+		 * mode.
 		 */
+		if (cap_enter() < 0)
+			err(-1, "cap_enter");
 
 		/*
 		 * Scrub the remainder of process state by calling fexecve(2)
 		 * the desired binary.
 		 */
-#ifdef LDSO_MODE
 		if (fexecve(fd_ldso, argv + 1, environ) < 0)
-#if 0
-		if (fexecve(fd_ldso, ldso_argv, environ) < 0)
-#endif
 			err(-1, "%s", LD_ELF_CAP_SO);
-#else
-		if (fexecve(fd_exec, argv + 1, environ) < 0)
-			err(-1, "%s", argv[1]);
-#endif
 		/* NOTREACHED */
 	}
 


More information about the p4-projects mailing list