Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 4 Nov 2010 19:32:32 +0000 (UTC)
From:      Jamie Gritton <jamie@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r214805 - projects/jailconf/usr.sbin/jail
Message-ID:  <201011041932.oA4JWWhr070771@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jamie
Date: Thu Nov  4 19:32:32 2010
New Revision: 214805
URL: http://svn.freebsd.org/changeset/base/214805

Log:
  Check unmounts for a mount point of the right FS type.

Modified:
  projects/jailconf/usr.sbin/jail/command.c

Modified: projects/jailconf/usr.sbin/jail/command.c
==============================================================================
--- projects/jailconf/usr.sbin/jail/command.c	Thu Nov  4 19:24:21 2010	(r214804)
+++ projects/jailconf/usr.sbin/jail/command.c	Thu Nov  4 19:32:32 2010	(r214805)
@@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$");
 
 #include <sys/types.h>
 #include <sys/event.h>
+#include <sys/mount.h>
 #include <sys/stat.h>
 #include <sys/sysctl.h>
 #include <sys/user.h>
@@ -69,7 +70,7 @@ static void add_proc(struct cfjail *j, p
 static void clear_procs(struct cfjail *j);
 static struct cfjail *find_proc(pid_t pid);
 static int check_path(struct cfjail *j, const char *pname, const char *path,
-    int isfile);
+    int isfile, const char *umount_type);
 
 static struct cfjails sleeping = TAILQ_HEAD_INITIALIZER(sleeping);
 static struct cfjails runnable = TAILQ_HEAD_INITIALIZER(runnable);
@@ -207,8 +208,11 @@ run_command(struct cfjail *j, int *plimi
 			failed(j);
 			return -1;
 		}
-		if (check_path(j, j->intparams[comparam]->name, argv[1], 0) < 0)
+		if (check_path(j, j->intparams[comparam]->name, argv[1], 0,
+		    down ? argv[2] : NULL) < 0) {
+			failed(j);
 			return -1;
+		}
 		if (down) {
 			argv[4] = NULL;
 			argv[3] = argv[1];
@@ -238,8 +242,11 @@ run_command(struct cfjail *j, int *plimi
 		}
 		devpath = alloca(strlen(path) + 5);
 		sprintf(devpath, "%s/dev", path);
-		if (check_path(j, "mount.devfs", devpath, 0) < 0)
+		if (check_path(j, "mount.devfs", devpath, 0,
+		    down ? "devfs" : NULL) < 0) {
+			failed(j);
 			return -1;
+		}
 		if (down) {
 			argv = alloca(3 * sizeof(char *));
 			*(const char **)&argv[0] = "/sbin/umount";
@@ -316,8 +323,10 @@ run_command(struct cfjail *j, int *plimi
 	consfd = 0;
 	if (injail &&
 	    (conslog = string_param(j->intparams[IP_EXEC_CONSOLELOG]))) {
-		if (check_path(j, "exec.consolelog", conslog, 1) < 0)
+		if (check_path(j, "exec.consolelog", conslog, 1, NULL) < 0) {
+			failed(j);
 			return -1;
+		}
 		consfd =
 		    open(conslog, O_WRONLY | O_CREAT | O_APPEND, DEFFILEMODE);
 		if (consfd < 0) {
@@ -683,9 +692,11 @@ get_user_info(struct cfjail *j, const ch
  * with no symlinks.
  */
 static int
-check_path(struct cfjail *j, const char *pname, const char *path, int isfile)
+check_path(struct cfjail *j, const char *pname, const char *path, int isfile,
+    const char *umount_type)
 {
-	struct stat st;
+	struct stat st, mpst;
+	struct statfs stfs;
 	char *tpath, *p;
 	const char *jailpath;
 	size_t jplen;
@@ -693,7 +704,6 @@ check_path(struct cfjail *j, const char 
 	if (path[0] != '/') {
 		jail_warnx(j, "%s: %s: not an absolute pathname",
 		    pname, path);
-		failed(j);
 		return -1;
 	}
 	/*
@@ -704,30 +714,50 @@ check_path(struct cfjail *j, const char 
 	if (jailpath == NULL)
 		jailpath = "";
 	jplen = strlen(jailpath);
-	if (strncmp(path, jailpath, jplen) || path[jplen] != '/')
-		return 0;
-	tpath = alloca(strlen(path) + 1);
-	strcpy(tpath, path);
-	for (p = tpath + jplen; p != NULL; ) {
-		p = strchr(p + 1, '/');
-		if (p)
-			*p = '\0';
-		if (lstat(tpath, &st) < 0) {
-			if (errno == ENOENT && isfile && !p)
-				break;
-			jail_warnx(j, "%s: %s: %s", pname, tpath,
+	if (!strncmp(path, jailpath, jplen) && path[jplen] == '/') {
+		tpath = alloca(strlen(path) + 1);
+		strcpy(tpath, path);
+		for (p = tpath + jplen; p != NULL; ) {
+			p = strchr(p + 1, '/');
+			if (p)
+				*p = '\0';
+			if (lstat(tpath, &st) < 0) {
+				if (errno == ENOENT && isfile && !p)
+					break;
+				jail_warnx(j, "%s: %s: %s", pname, tpath,
+				    strerror(errno));
+				return -1;
+			}
+			if (S_ISLNK(st.st_mode)) {
+				jail_warnx(j, "%s: %s is a symbolic link",
+				    pname, tpath);
+				return -1;
+			}
+			if (p)
+				*p = '/';
+		}
+	}
+	if (umount_type != NULL) {
+		if (stat(path, &st) < 0 || statfs(path, &stfs) < 0) {
+			jail_warnx(j, "%s: %s: %s", pname, path,
 			    strerror(errno));
-			failed(j);
 			return -1;
 		}
-		if (S_ISLNK(st.st_mode)) {
-			jail_warnx(j, "%s: %s is a symbolic link",
-			    pname, tpath);
-			failed(j);
+		if (stat(stfs.f_mntonname, &mpst) < 0) {
+			jail_warnx(j, "%s: %s: %s", pname, stfs.f_mntonname,
+			    strerror(errno));
+			return -1;
+		}
+		if (st.st_ino != mpst.st_ino) {
+			jail_warnx(j, "%s: %s: not a mount point",
+			    pname, path);
+			return -1;
+		}
+		if (strcmp(stfs.f_fstypename, umount_type)) {
+			jail_warnx(j, "%s: %s: not a %s mount",
+			    pname, path, umount_type);
 			return -1;
 		}
-		if (p)
-			*p = '/';
 	}
 	return 0;
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201011041932.oA4JWWhr070771>