[master] 53bd4ae Move creation of workdir into jail code, and use the master HIGH/LOW around socket operations which may be on reserved ports.

Poul-Henning Kamp phk at FreeBSD.org
Wed Feb 18 20:10:32 CET 2015


commit 53bd4aeb4889da3aa35f3adb6147aa7bfa789779
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Wed Feb 18 19:10:01 2015 +0000

    Move creation of workdir into jail code, and use the master HIGH/LOW
    around socket operations which may be on reserved ports.

diff --git a/bin/varnishd/mgt/mgt_child.c b/bin/varnishd/mgt/mgt_child.c
index 5a0220e..c116c5f 100644
--- a/bin/varnishd/mgt/mgt_child.c
+++ b/bin/varnishd/mgt/mgt_child.c
@@ -229,6 +229,7 @@ MGT_open_sockets(void)
 	struct listen_sock *ls;
 	int good = 0;
 
+	VJ_master(JAIL_MASTER_HIGH);
 	VTAILQ_FOREACH(ls, &heritage.socks, list) {
 		if (ls->sock >= 0) {
 			good++;
@@ -242,6 +243,7 @@ MGT_open_sockets(void)
 
 		good++;
 	}
+	VJ_master(JAIL_MASTER_LOW);
 	if (!good)
 		return (1);
 	return (0);
diff --git a/bin/varnishd/mgt/mgt_cli.c b/bin/varnishd/mgt/mgt_cli.c
index d35d42c..84446aa 100644
--- a/bin/varnishd/mgt/mgt_cli.c
+++ b/bin/varnishd/mgt/mgt_cli.c
@@ -535,7 +535,9 @@ mgt_cli_telnet(const char *T_arg)
 	vsb = VSB_new_auto();
 	XXXAN(vsb);
 	for (i = 0; i < n; ++i) {
+		VJ_master(JAIL_MASTER_HIGH);
 		sock = VSS_listen(ta[i], 10);
+		VJ_master(JAIL_MASTER_LOW);
 		if (sock < 0)
 			continue;
 		VTCP_myname(sock, abuf, sizeof abuf, pbuf, sizeof pbuf);
diff --git a/bin/varnishd/mgt/mgt_jail_unix.c b/bin/varnishd/mgt/mgt_jail_unix.c
index bfb65dd..11792af 100644
--- a/bin/varnishd/mgt/mgt_jail_unix.c
+++ b/bin/varnishd/mgt/mgt_jail_unix.c
@@ -31,11 +31,13 @@
 #include "config.h"
 
 #include <pwd.h>
+#include <fcntl.h>
 #include <grp.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <sys/stat.h>
 
 #include "mgt/mgt.h"
 
@@ -100,6 +102,8 @@ vju_init(char **args)
 			return (1);
 		if (vju_getuid(JAIL_USER))
 			return (1);
+		AZ(setegid(vju_gid));
+		AZ(seteuid(vju_uid));
 		return (0);
 	}
 
@@ -108,17 +112,15 @@ vju_init(char **args)
 
 	for (;*args != NULL; args++) {
 		if (!strncmp(*args, "user=", 5)) {
-			if (vju_getuid((*args) + 5)) {
+			if (vju_getuid((*args) + 5))
 				ARGV_ERR("Unix jail: %s user not found.\n",
 				    (*args) + 5);
-			}
 			continue;
 		}
 		if (!strncmp(*args, "ccgroup=", 8)) {
-			if (vju_getccgid((*args) + 8)) {
+			if (vju_getccgid((*args) + 8))
 				ARGV_ERR("Unix jail: %s group not found.\n",
 				    (*args) + 8);
-			}
 			continue;
 		}
 		ARGV_ERR("Unix jail: unknown sub-argument '%s'\n", *args);
@@ -127,13 +129,19 @@ vju_init(char **args)
 	if (vju_user == NULL && vju_getuid(JAIL_USER))
 		ARGV_ERR("Unix jail: %s user not found.\n", JAIL_USER);
 
+	/* Do an explicit JAIL_MASTER_LOW */
+	AZ(setegid(vju_gid));
+	AZ(seteuid(vju_uid));
 	return (0);
 }
 
 static void __match_proto__(jail_master_f)
 vju_master(enum jail_master_e jme)
 {
-	(void)jme;
+	if (jme == JAIL_MASTER_HIGH)
+		AZ(seteuid(0));
+	else
+		AZ(seteuid(vju_uid));
 }
 
 static void __match_proto__(jail_subproc_f)
@@ -142,6 +150,7 @@ vju_subproc(enum jail_subproc_e jse)
 	int i;
 	gid_t gid_list[NGID];
 
+	AZ(seteuid(0));
 	AZ(setgid(vju_gid));
 	AZ(initgroups(vju_user, vju_gid));
 
@@ -166,10 +175,42 @@ vju_subproc(enum jail_subproc_e jse)
 #endif
 }
 
+static void
+vju_make_workdir(const char *dname)
+{
+	int fd;
+
+	AZ(seteuid(0));
+
+	if (mkdir(dname, 0755) < 0 && errno != EEXIST)
+		ARGV_ERR("Cannot create working directory '%s': %s\n",
+		    dname, strerror(errno));
+
+	if (chown(dname, vju_uid, vju_gid) < 0)
+		ARGV_ERR(
+		    "Cannot set owner/group on working directory '%s': %s\n",
+		    dname, strerror(errno));
+
+	if (chdir(dname) < 0)
+		ARGV_ERR("Cannot change to working directory '%s': %s\n",
+		    dname, strerror(errno));
+
+	AZ(seteuid(vju_uid));
+
+	fd = open("_.testfile", O_RDWR|O_CREAT|O_EXCL, 0600);
+	if (fd < 0)
+		ARGV_ERR("Error: Cannot create test-file in %s (%s)\n"
+		    "Check permissions (or delete old directory)\n",
+		    dname, strerror(errno));
+	AZ(close(fd));
+	AZ(unlink("_.testfile"));
+}
+
 const struct jail_tech jail_tech_unix = {
 	.magic =	JAIL_TECH_MAGIC,
 	.name =		"unix",
 	.init =		vju_init,
 	.master =	vju_master,
+	.make_workdir =	vju_make_workdir,
 	.subproc =	vju_subproc,
 };



More information about the varnish-commit mailing list