Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [day] [month] [year] [list]
Date: Tue, 31 Jul 2012 21:52:46 +0400
From: Vasily Kulikov <segoon@...nwall.com>
To: owl-dev@...ts.openwall.com
Subject: vzctl bitness_lock patch

Hi,

The patch for bitness_lock feature is attached.

It seems vzctl needs only BITNESS_LOCK_ON_EXEC, BITNESS_LOCK (just lock
current process) is not needed.  I suppose we can even lock CT after it
is started without bitness locking using CPT and restarting each process
(I didn't investigate whether it is actually true, though).  E.g. CPT
on modern upstream kernel is implemented in userspace by recreating the
whole process tree, where it is trivially to add prctl() before
executing the actual restorer.

Thanks,

-- 
Vasily

Двоичные файлы vzctl-3.0.23.old/fedora-15-x86_64.tar.gz и vzctl-3.0.23/fedora-15-x86_64.tar.gz различаются
Двоичные файлы vzctl-3.0.23.old/fedora-15-x86.tar.gz и vzctl-3.0.23/fedora-15-x86.tar.gz различаются
diff -uNrp -x debian -x etc -x tags -x vzc.patch vzctl-3.0.23.old/include/res.h vzctl-3.0.23/include/res.h
--- vzctl-3.0.23.old/include/res.h	2008-10-30 16:24:43.000000000 +0300
+++ vzctl-3.0.23/include/res.h	2012-07-31 21:14:15.425296126 +0400
@@ -99,6 +99,7 @@ typedef struct {
 	int start_force;
 	int setmode;
 	int onboot;
+	int bitness_lock;
 	char *config;
 	char *origin_sample;
 	char *lockdir;
diff -uNrp -x debian -x etc -x tags -x vzc.patch vzctl-3.0.23.old/include/vzctl.h vzctl-3.0.23/include/vzctl.h
--- vzctl-3.0.23.old/include/vzctl.h	2008-10-30 16:24:43.000000000 +0300
+++ vzctl-3.0.23/include/vzctl.h	2012-07-27 14:05:51.953926021 +0400
@@ -54,6 +54,11 @@
 #define UNLCPUUNITS		1000
 #define HNCPUUNITS		1000
 
+extern int bitness_lock;
+
+int set_bitness_lock(void);
+
+
 /* setmode flags */
 enum {
 	SET_NONE = 0,
diff -uNrp -x debian -x etc -x tags -x vzc.patch vzctl-3.0.23.old/include/vzctl_param.h vzctl-3.0.23/include/vzctl_param.h
--- vzctl-3.0.23.old/include/vzctl_param.h	2008-10-30 16:24:43.000000000 +0300
+++ vzctl-3.0.23/include/vzctl_param.h	2012-07-31 21:14:03.225235648 +0400
@@ -135,5 +135,7 @@
 #define PARAM_NETIF_BRIDGE	361
 #define PARAM_DESCRIPTION	362
 
+#define PARAM_BITNESS_LOCK  400
+
 #define PARAM_LINE		"e:p:f:t:i:l:k:a:b:n:x:h"
 #endif
diff -uNrp -x debian -x etc -x tags -x vzc.patch vzctl-3.0.23.old/man/vzctl.8 vzctl-3.0.23/man/vzctl.8
--- vzctl-3.0.23.old/man/vzctl.8	2008-10-30 16:24:43.000000000 +0300
+++ vzctl-3.0.23/man/vzctl.8	2012-07-31 20:54:45.963497141 +0400
@@ -338,6 +338,13 @@ limit is 0 (no CPU limit).
 \fB--cpus\fR \fInum\fR
 sets number of CPUs available in the container.
 .TP
+\fB--bitness_lock\fR \fIbits\fR
+Limits bitness of CT processes to a specific bitness.
+Either 32 or 64.
+If CT has nonzero bitness_lock all binaries of another bitness cannot be
+executed and any process trying to do a system call of another bitness will be
+immediatelly killed by SIGKILL.
+.TP
 \fBMemory output parameters\fR
 
 This parameter control output of /proc/meminfo inside a container 
diff -uNrp -x debian -x etc -x tags -x vzc.patch vzctl-3.0.23.old/src/enter.c vzctl-3.0.23/src/enter.c
--- vzctl-3.0.23.old/src/enter.c	2012-07-26 21:08:52.726783092 +0400
+++ vzctl-3.0.23/src/enter.c	2012-07-31 20:14:52.547628480 +0400
@@ -310,7 +310,9 @@ int do_enter(vps_handler *h, envid_t vei
 				snprintf(buf, sizeof(buf), "TERM=%s", term);
 				env[sizeof(env)/sizeof(env[0]) - 2] = buf;
 			}
+			set_bitness_lock();
 			execve("/bin/bash", arg, env);
+			set_bitness_lock();
 			execve("/bin/sh", arg, env);
 			logger(-1, errno, "enter failed: unable to exec bash");
 			exit(1);
diff -uNrp -x debian -x etc -x tags -x vzc.patch vzctl-3.0.23.old/src/lib/config.c vzctl-3.0.23/src/lib/config.c
--- vzctl-3.0.23.old/src/lib/config.c	2008-10-30 16:24:43.000000000 +0300
+++ vzctl-3.0.23/src/lib/config.c	2012-07-31 21:16:17.581901796 +0400
@@ -44,6 +44,7 @@
 #include "meminfo.h"
 #include "vzfeatures.h"
 #include "io.h"
+#include "exec.h"
 
 static int _page_size;
 static int check_name(char *name);
@@ -131,6 +132,7 @@ static vps_config config[] = {
 
 {"FEATURES",	NULL, PARAM_FEATURES},
 {"IOPRIO",	NULL, PARAM_IOPRIO},
+{"BITNESS_LOCK",	NULL, PARAM_BITNESS_LOCK},
 {NULL		,NULL, -1}
 };
 
@@ -165,6 +167,7 @@ static struct option set_opt[] = {
 {"avnumproc",	required_argument, NULL, PARAM_AVNUMPROC},
 /*	Capability */
 {"capability",	required_argument, NULL, PARAM_CAP},
+{"bitness_lock",	required_argument, NULL, PARAM_BITNESS_LOCK},
 /*	Network	*/
 {"ipadd",	required_argument, NULL, PARAM_IP_ADD},
 {"ip",		required_argument, NULL, PARAM_IP_ADD},
@@ -378,6 +381,15 @@ int conf_store_yesno(list_head_t *conf, 
 	return 0;
 }
 
+int parse_bitness_lock(int *res, char *val)
+{
+	if (parse_int(val, res))
+		return ERR_INVAL;
+	if (*res != 32 && *res != 64 && *res != 0)
+		return ERR_INVAL;
+	return 0;
+}
+
 /******************** Features *************************/
 static int parse_features(env_param *env, char *val)
 {
@@ -1287,6 +1299,11 @@ static int store_cpu(vps_param *old_p, v
 			conf->name, *cpu->limit);
 		add_str_param(conf_h, buf);
 		break;
+	case PARAM_BITNESS_LOCK:
+		snprintf(buf, sizeof(buf), "%s=\"%lu\"",
+				conf->name, vps_p->opt.bitness_lock);
+		add_str_param(conf_h, buf);
+		break;
 	case PARAM_VCPUS:
 		if (cpu->vcpus == NULL)
 			break;
@@ -1957,6 +1974,9 @@ static int parse(envid_t veid, vps_param
 	case PARAM_CAP:
 		ret = parse_cap(val, &vps_p->res.cap);
 		break;
+	case PARAM_BITNESS_LOCK:
+		ret = parse_bitness_lock(&vps_p->opt.bitness_lock, val);
+		break;
 	case PARAM_IP_ADD:
 	case PARAM_IP_DEL:
 		ret = parse_ip(vps_p, val, id);
@@ -2679,6 +2699,7 @@ static void merge_opt(vps_opt *dst, vps_
 	MERGE_INT(onboot);
 	MERGE_INT(setmode);
 	MERGE_INT(apply_cfg_map);
+	MERGE_INT(bitness_lock);
 
 	MERGE_STR(config)
 	MERGE_STR(origin_sample)
diff -uNrp -x debian -x etc -x tags -x vzc.patch vzctl-3.0.23.old/src/lib/env.c vzctl-3.0.23/src/lib/env.c
--- vzctl-3.0.23.old/src/lib/env.c	2008-10-30 16:24:43.000000000 +0300
+++ vzctl-3.0.23/src/lib/env.c	2012-07-31 20:17:13.904329743 +0400
@@ -400,8 +400,11 @@ try:
 		dup2(fd, 2);
 	}
 	logger(10, 0, "Starting init");
+	set_bitness_lock();
 	execve("/sbin/init", argv, envp);
+	set_bitness_lock();
 	execve("/etc/init", argv, envp);
+	set_bitness_lock();
 	execve("/bin/init", argv, envp);
 
 	ret = VZ_FS_BAD_TMPL;
diff -uNrp -x debian -x etc -x tags -x vzc.patch vzctl-3.0.23.old/src/lib/exec.c vzctl-3.0.23/src/lib/exec.c
--- vzctl-3.0.23.old/src/lib/exec.c	2012-07-26 21:08:52.726783092 +0400
+++ vzctl-3.0.23/src/lib/exec.c	2012-07-31 21:18:55.322684210 +0400
@@ -28,14 +28,32 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <string.h>
+#include <sys/prctl.h>
 
 #include "vzerror.h"
 #include "exec.h"
+#include "vzctl.h"
 #include "env.h"
 #include "util.h"
 #include "logger.h"
 #include "script.h"
 
+#define   PR_BITNESS_LOCK_ON_EXEC 35
+
+int bitness_lock;
+
+int set_bitness_lock(void)
+{
+	if (bitness_lock) {
+		if (prctl(PR_BITNESS_LOCK_ON_EXEC, 1, bitness_lock, 0, 0)) {
+			perror("prctl");
+			exit(1);
+		}
+	}
+	return 0;
+}
+
+
 static volatile sig_atomic_t alarm_flag, child_exited;
 static char *argv_bash[] = {"bash", NULL};
 static char *envp_bash[] = {"HOME=/", "TERM=linux",
@@ -65,6 +83,7 @@ int execvep(const char *path, char *cons
 				strcat(partial, "/");
 			strcat(partial, path);
 
+			set_bitness_lock();
 			execve(partial, argv, envp != NULL ? envp : envp_bash);
 
 			if (errno != ENOENT)
@@ -76,8 +95,10 @@ int execvep(const char *path, char *cons
 			}
 		}
 		return -1;
-	} else
+	} else {
+		set_bitness_lock();
 		return execve(path, argv, envp);
+	}
 }
 
 static int stdredir(int rdfd, int wrfd)
@@ -217,8 +238,10 @@ static int vps_real_exec(vps_handler *h,
 		if (exec_mode == MODE_EXEC && argv != NULL) {
 			execvep(argv[0], argv, envp);
 		} else {
+			set_bitness_lock();
 			execve("/bin/bash", argv != NULL ? argv : argv_bash,
 					envp);
+			set_bitness_lock();
 			execve("/bin/sh", argv != NULL ? argv : argv_bash,
 					envp);
 		}
diff -uNrp -x debian -x etc -x tags -x vzc.patch vzctl-3.0.23.old/src/vzctl-actions.c vzctl-3.0.23/src/vzctl-actions.c
--- vzctl-3.0.23.old/src/vzctl-actions.c	2008-10-30 16:24:43.000000000 +0300
+++ vzctl-3.0.23/src/vzctl-actions.c	2012-07-31 21:23:12.719960446 +0400
@@ -815,6 +815,8 @@ int run_action(envid_t veid, int action,
 	ret = 0;
 	if ((h = vz_open(veid)) == NULL)
 		return VZ_BAD_KERNEL;
+
+    bitness_lock = g_p->opt.bitness_lock;
 	if (action != ACTION_EXEC &&
 		action != ACTION_EXEC2 &&
 		action != ACTION_EXEC3 &&

Powered by blists - more mailing lists

Your e-mail address:

Powered by Openwall GNU/*/Linux - Powered by OpenVZ