From owner-svn-src-all@freebsd.org Wed Nov 18 21:07:09 2020 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 987B8471ED0; Wed, 18 Nov 2020 21:07:09 +0000 (UTC) (envelope-from oshogbo@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4CbwNs3hzZz4ftx; Wed, 18 Nov 2020 21:07:09 +0000 (UTC) (envelope-from oshogbo@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 6D9E818809; Wed, 18 Nov 2020 21:07:09 +0000 (UTC) (envelope-from oshogbo@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 0AIL79mP053578; Wed, 18 Nov 2020 21:07:09 GMT (envelope-from oshogbo@FreeBSD.org) Received: (from oshogbo@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 0AIL78pi053574; Wed, 18 Nov 2020 21:07:08 GMT (envelope-from oshogbo@FreeBSD.org) Message-Id: <202011182107.0AIL78pi053574@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: oshogbo set sender to oshogbo@FreeBSD.org using -f From: Mariusz Zaborski Date: Wed, 18 Nov 2020 21:07:08 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r367819 - in head: sys/kern sys/sys usr.sbin/jail X-SVN-Group: head X-SVN-Commit-Author: oshogbo X-SVN-Commit-Paths: in head: sys/kern sys/sys usr.sbin/jail X-SVN-Commit-Revision: 367819 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Nov 2020 21:07:09 -0000 Author: oshogbo Date: Wed Nov 18 21:07:08 2020 New Revision: 367819 URL: https://svnweb.freebsd.org/changeset/base/367819 Log: jail: introduce per jail suser_enabled setting The suser_enable sysctl allows to remove a privileged rights from uid 0. This change introduce per jail setting which allow to make root a normal user. Reviewed by: jamie Previous version reviewed by: kevans, emaste, markj, me_igalic.co Discussed with: pjd Differential Revision: https://reviews.freebsd.org/D27128 Modified: head/sys/kern/kern_jail.c head/sys/kern/kern_priv.c head/sys/sys/jail.h head/usr.sbin/jail/jail.8 Modified: head/sys/kern/kern_jail.c ============================================================================== --- head/sys/kern/kern_jail.c Wed Nov 18 20:59:58 2020 (r367818) +++ head/sys/kern/kern_jail.c Wed Nov 18 21:07:08 2020 (r367819) @@ -199,12 +199,14 @@ static struct bool_flags pr_flag_allow[NBBY * NBPW] = {"allow.read_msgbuf", "allow.noread_msgbuf", PR_ALLOW_READ_MSGBUF}, {"allow.unprivileged_proc_debug", "allow.nounprivileged_proc_debug", PR_ALLOW_UNPRIV_DEBUG}, + {"allow.suser", "allow.nosuser", PR_ALLOW_SUSER}, }; const size_t pr_flag_allow_size = sizeof(pr_flag_allow); #define JAIL_DEFAULT_ALLOW (PR_ALLOW_SET_HOSTNAME | \ PR_ALLOW_RESERVED_PORTS | \ - PR_ALLOW_UNPRIV_DEBUG) + PR_ALLOW_UNPRIV_DEBUG | \ + PR_ALLOW_SUSER) #define JAIL_DEFAULT_ENFORCE_STATFS 2 #define JAIL_DEFAULT_DEVFS_RSNUM 0 static unsigned jail_default_allow = JAIL_DEFAULT_ALLOW; @@ -3815,6 +3817,8 @@ SYSCTL_JAIL_PARAM(_allow, read_msgbuf, CTLTYPE_INT | C "B", "Jail may read the kernel message buffer"); SYSCTL_JAIL_PARAM(_allow, unprivileged_proc_debug, CTLTYPE_INT | CTLFLAG_RW, "B", "Unprivileged processes may use process debugging facilities"); +SYSCTL_JAIL_PARAM(_allow, suser, CTLTYPE_INT | CTLFLAG_RW, + "B", "Processes in jail with uid 0 have privilege"); SYSCTL_JAIL_PARAM_SUBNODE(allow, mount, "Jail mount/unmount permission flags"); SYSCTL_JAIL_PARAM(_allow_mount, , CTLTYPE_INT | CTLFLAG_RW, Modified: head/sys/kern/kern_priv.c ============================================================================== --- head/sys/kern/kern_priv.c Wed Nov 18 20:59:58 2020 (r367818) +++ head/sys/kern/kern_priv.c Wed Nov 18 21:07:08 2020 (r367819) @@ -3,6 +3,7 @@ * * Copyright (c) 2006 nCircle Network Security, Inc. * Copyright (c) 2009 Robert N. M. Watson + * Copyright (c) 2020 Mariusz Zaborski * All rights reserved. * * This software was developed by Robert N. M. Watson for the TrustedBSD @@ -36,6 +37,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include +#include #include #include #include @@ -54,10 +58,58 @@ __FBSDID("$FreeBSD$"); * userland programs, and should not be done without careful consideration of * the consequences. */ -static int __read_mostly suser_enabled = 1; -SYSCTL_INT(_security_bsd, OID_AUTO, suser_enabled, CTLFLAG_RWTUN, - &suser_enabled, 0, "processes with uid 0 have privilege"); +static bool +suser_enabled(struct ucred *cred) +{ + + return (prison_allow(cred, PR_ALLOW_SUSER) ? true : false); +} + +static void inline +prison_suser_set(struct prison *pr, int enabled) +{ + + if (enabled) { + pr->pr_allow |= PR_ALLOW_SUSER; + } else { + pr->pr_allow &= ~PR_ALLOW_SUSER; + } +} + +static int +sysctl_kern_suser_enabled(SYSCTL_HANDLER_ARGS) +{ + struct prison *pr, *cpr; + struct ucred *cred; + int descend, error, enabled; + + cred = req->td->td_ucred; + enabled = suser_enabled(cred); + + error = sysctl_handle_int(oidp, &enabled, 0, req); + if (error || !req->newptr) + return (error); + + pr = cred->cr_prison; + sx_slock(&allprison_lock); + mtx_lock(&pr->pr_mtx); + + prison_suser_set(pr, enabled); + if (!enabled) { + FOREACH_PRISON_DESCENDANT_LOCKED(pr, cpr, descend) { + prison_suser_set(cpr, 0); + } + } + mtx_unlock(&pr->pr_mtx); + sx_sunlock(&allprison_lock); + return (0); +} + +SYSCTL_PROC(_security_bsd, OID_AUTO, suser_enabled, CTLTYPE_INT | + CTLFLAG_RWTUN | CTLFLAG_PRISON, 0, 0, &sysctl_kern_suser_enabled, "I", + "Processes with uid 0 have privilege"); + static int unprivileged_mlock = 1; SYSCTL_INT(_security_bsd, OID_AUTO, unprivileged_mlock, CTLFLAG_RWTUN, &unprivileged_mlock, 0, "Allow non-root users to call mlock(2)"); @@ -186,7 +238,7 @@ priv_check_cred(struct ucred *cred, int priv) * superuser policy to be globally disabled, although this is * currenty of limited utility. */ - if (suser_enabled) { + if (suser_enabled(cred)) { switch (priv) { case PRIV_MAXFILES: case PRIV_MAXPROC: @@ -258,7 +310,7 @@ priv_check_cred_vfs_lookup_slow(struct ucred *cred) if (error) goto out; - if (cred->cr_uid == 0 && suser_enabled) { + if (cred->cr_uid == 0 && suser_enabled(cred)) { error = 0; goto out; } @@ -279,7 +331,7 @@ priv_check_cred_vfs_lookup(struct ucred *cred) return (priv_check_cred_vfs_lookup_slow(cred)); error = EPERM; - if (cred->cr_uid == 0 && suser_enabled) + if (cred->cr_uid == 0 && suser_enabled(cred)) error = 0; return (error); } @@ -294,7 +346,7 @@ priv_check_cred_vfs_lookup_nomac(struct ucred *cred) return (EAGAIN); error = EPERM; - if (cred->cr_uid == 0 && suser_enabled) + if (cred->cr_uid == 0 && suser_enabled(cred)) error = 0; return (error); } @@ -313,7 +365,7 @@ priv_check_cred_vfs_generation_slow(struct ucred *cred goto out; } - if (cred->cr_uid == 0 && suser_enabled) { + if (cred->cr_uid == 0 && suser_enabled(cred)) { error = 0; goto out; } @@ -334,7 +386,7 @@ priv_check_cred_vfs_generation(struct ucred *cred) return (priv_check_cred_vfs_generation_slow(cred)); error = EPERM; - if (!jailed(cred) && cred->cr_uid == 0 && suser_enabled) + if (!jailed(cred) && cred->cr_uid == 0 && suser_enabled(cred)) error = 0; return (error); } Modified: head/sys/sys/jail.h ============================================================================== --- head/sys/sys/jail.h Wed Nov 18 20:59:58 2020 (r367818) +++ head/sys/sys/jail.h Wed Nov 18 21:07:08 2020 (r367819) @@ -232,9 +232,10 @@ struct prison_racct { #define PR_ALLOW_MLOCK 0x00000080 #define PR_ALLOW_READ_MSGBUF 0x00000100 #define PR_ALLOW_UNPRIV_DEBUG 0x00000200 +#define PR_ALLOW_SUSER 0x00000400 #define PR_ALLOW_RESERVED_PORTS 0x00008000 #define PR_ALLOW_KMEM_ACCESS 0x00010000 /* reserved, not used yet */ -#define PR_ALLOW_ALL_STATIC 0x000183ff +#define PR_ALLOW_ALL_STATIC 0x000187ff /* * PR_ALLOW_DIFFERENCES determines which flags are able to be Modified: head/usr.sbin/jail/jail.8 ============================================================================== --- head/usr.sbin/jail/jail.8 Wed Nov 18 20:59:58 2020 (r367818) +++ head/usr.sbin/jail/jail.8 Wed Nov 18 21:07:08 2020 (r367819) @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 14, 2020 +.Dd November 18, 2020 .Dt JAIL 8 .Os .Sh NAME @@ -587,6 +587,13 @@ and resource limits. The jail root may bind to ports lower than 1024. .It Va allow.unprivileged_proc_debug Unprivileged processes in the jail may use debugging facilities. +.It Va allow.suser +The value of the jail's +.Va security.bsd.suser_enabled +sysctl. +The super-user will be disabled automatically if its parent system has it +disabled. +The super-user is enabled by default. .El .El .Pp @@ -1267,6 +1274,7 @@ Changes to these variables by a jailed process do not environment, only the jail environment. These variables are .Va kern.securelevel , +.Va security.bsd.suser_enabled , .Va kern.hostname , .Va kern.domainname , .Va kern.hostid ,