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
This commit is contained in:
parent
21fe9441e1
commit
05e1e482c7
@ -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 | CTLFLAG_RW,
|
||||
"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,
|
||||
|
@ -3,6 +3,7 @@
|
||||
*
|
||||
* Copyright (c) 2006 nCircle Network Security, Inc.
|
||||
* Copyright (c) 2009 Robert N. M. Watson
|
||||
* Copyright (c) 2020 Mariusz Zaborski <oshogbo@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Robert N. M. Watson for the TrustedBSD
|
||||
@ -36,6 +37,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/param.h>
|
||||
#include <sys/jail.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/sx.h>
|
||||
#include <sys/priv.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/sdt.h>
|
||||
@ -54,9 +58,57 @@ __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,
|
||||
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 affect the host
|
||||
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 ,
|
||||
|
Loading…
Reference in New Issue
Block a user