Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 22 Apr 2005 12:47:46 +0200 (CEST)
From:      Frank Behrens <frank@pinky.sax.de>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   bin/80242: jail(8) should be able to set kern.securelevel inside the prison
Message-ID:  <200504221047.j3MAlk8X094731@moon.behrens>
Resent-Message-ID: <200504221050.j3MAoIti093267@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         80242
>Category:       bin
>Synopsis:       jail(8) should be able to set kern.securelevel inside the prison
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri Apr 22 10:50:18 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Frank Behrens
>Release:        FreeBSD 5.4-STABLE i386
>Organization:
>Environment:
System: FreeBSD moon.behrens 5.4-STABLE FreeBSD 5.4-STABLE #2: Tue Apr 12 10:41:41 CEST 2005 root@moon.behrens:/data2/sys/obj/usr/src/sys/FRANK01 i386
>Description:
jail(8) should be able to set kern.securelevel

As described in man jail(8) the kern.securelevel in a jail can raised independent
of host securelevel. If the jail is run with a user other than root
(option -u or -U) this user can not change the securelevel. Therefore
the securelevel must raised before the user is changed and this can
be done in jail(8) only.

jail(8) needs an option to be able to raise the securelevel in a jail
if the jail is run with a restricted user. A workaround would be
a suid executable inside the jail, but this is refused due to
security constraints.

>How-To-Repeat:
Start a jail with other user (option -u or -U) and try to raise
the securelevel in the jail without any suid executable.
>Fix:
The following patch implements the option to raise the
kern.securelevel inside a newly created jail.


--- jailseclevel.patch begins here ---
--- usr.sbin/jail/jail.8.orig	Sun Feb 27 16:40:16 2005
+++ usr.sbin/jail/jail.8	Thu Apr 21 10:43:33 2005
@@ -33,7 +33,7 @@
 .\"
 .\" $FreeBSD: src/usr.sbin/jail/jail.8,v 1.58.2.2 2005/02/27 15:40:16 brueffer Exp $
 .\"
-.Dd April 8, 2003
+.Dd April 21, 2005
 .Dt JAIL 8
 .Os
 .Sh NAME
@@ -42,6 +42,7 @@
 .Sh SYNOPSIS
 .Nm
 .Op Fl i
+.Op Fl s Ar securelevel
 .Op Fl l u Ar username | Fl U Ar username
 .Ar path hostname ip-number command ...
 .Sh DESCRIPTION
@@ -53,6 +54,8 @@
 .Bl -tag -width ".Fl u Ar username"
 .It Fl i
 Output the jail identifier of the newly created jail.
+.It Fl s Ar securelevel
+Sets "kern.securelevel" to the specified value inside the newly created jail.
 .It Fl l
 Run program in the clean environment.
 The environment is discarded except for
--- usr.sbin/jail/jail.c.orig	Sun Aug 15 10:21:50 2004
+++ usr.sbin/jail/jail.c	Thu Apr 21 10:39:00 2005
@@ -12,6 +12,7 @@
 
 #include <sys/param.h>
 #include <sys/jail.h>
+#include <sys/sysctl.h>
 
 #include <netinet/in.h>
 #include <arpa/inet.h>
@@ -28,6 +29,7 @@
 #include <unistd.h>
 
 static void	usage(void);
+static void	setsecurelevel (int level);
 extern char	**environ;
 
 #define GET_USER_INFO do {						\
@@ -57,15 +59,19 @@
 	char path[PATH_MAX], *username;
 	static char *cleanenv;
 	const char *shell, *p;
+	int securelevel = -1;
 
 	iflag = lflag = uflag = Uflag = 0;
 	username = cleanenv = NULL;
 
-	while ((ch = getopt(argc, argv, "ilu:U:")) != -1) {
+	while ((ch = getopt(argc, argv, "ils:u:U:")) != -1) {
 		switch (ch) {
 		case 'i':
 			iflag = 1;
 			break;
+		case 's':
+			securelevel = (int) strtol(optarg, NULL, 0);
+			break;
 		case 'u':
 			username = optarg;
 			uflag = 1;
@@ -109,6 +115,8 @@
 		printf("%d\n", i);
 		fflush(stdout);
 	}
+	if (securelevel > 0)
+		setsecurelevel(securelevel);
 	if (username != NULL) {
 		if (Uflag)
 			GET_USER_INFO;
@@ -148,7 +156,15 @@
 {
 
 	(void)fprintf(stderr, "%s%s\n",
-	     "usage: jail [-i] [-l -u username | -U username]",
+	     "usage: jail [-i] [-s securelevel] [-l -u username | -U username]",
 	     " path hostname ip-number command ...");
 	exit(1);
+}
+
+static void
+setsecurelevel (int level) {
+
+     if (sysctlbyname("kern.securelevel", NULL, 0, &level, sizeof(level)))
+	     err(1, "Can not set secure level to %d", level);
+
 }
--- jailseclevel.patch ends here ---


>Release-Note:
>Audit-Trail:
>Unformatted:



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