Change prison_add_vfs() to the more generic prison_add_allow(), which
can add any dynamic allow.* or allow.*.* parameter. Also keep prison_add_vfs() as a wrapper. Differential Revision: D16146
This commit is contained in:
parent
85ab1415ff
commit
0a1724045e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=336038
@ -3760,37 +3760,43 @@ SYSCTL_JAIL_PARAM(_allow_mount, , CTLTYPE_INT | CTLFLAG_RW,
|
||||
"B", "Jail may mount/unmount jail-friendly file systems in general");
|
||||
|
||||
/*
|
||||
* The VFS system will register jail-aware filesystems here. They each get
|
||||
* a parameter allow.mount.xxxfs and a flag to check when a jailed user
|
||||
* attempts to mount.
|
||||
* Add a dynamic parameter allow.<name>, or allow.<prefix>.<name>. Return
|
||||
* its associated bit in the pr_allow bitmask, or zero if the parameter was
|
||||
* not created.
|
||||
*/
|
||||
void
|
||||
prison_add_vfs(struct vfsconf *vfsp)
|
||||
unsigned
|
||||
prison_add_allow(const char *prefix, const char *name, const char *prefix_descr,
|
||||
const char *descr)
|
||||
{
|
||||
char *allow_name, *allow_noname, *mount_allowed;
|
||||
struct bool_flags *bf;
|
||||
struct sysctl_oid *parent;
|
||||
char *allow_name, *allow_noname, *allowed;
|
||||
#ifndef NO_SYSCTL_DESCR
|
||||
char *descr;
|
||||
char *descr_deprecated;
|
||||
#endif
|
||||
unsigned allow_flag;
|
||||
|
||||
if (asprintf(&allow_name, M_PRISON, "allow.mount.%s", vfsp->vfc_name) <
|
||||
0 || asprintf(&allow_noname, M_PRISON, "allow.mount.no%s",
|
||||
vfsp->vfc_name) < 0) {
|
||||
if (prefix
|
||||
? asprintf(&allow_name, M_PRISON, "allow.%s.%s", prefix, name)
|
||||
< 0 ||
|
||||
asprintf(&allow_noname, M_PRISON, "allow.%s.no%s", prefix, name)
|
||||
< 0
|
||||
: asprintf(&allow_name, M_PRISON, "allow.%s", name) < 0 ||
|
||||
asprintf(&allow_noname, M_PRISON, "allow.no%s", name) < 0) {
|
||||
free(allow_name, M_PRISON);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* See if this parameter has already beed added, i.e. if the filesystem
|
||||
* was previously loaded/unloaded.
|
||||
* See if this parameter has already beed added, i.e. a module was
|
||||
* previously loaded/unloaded.
|
||||
*/
|
||||
mtx_lock(&prison0.pr_mtx);
|
||||
for (bf = pr_flag_allow;
|
||||
bf < pr_flag_allow + nitems(pr_flag_allow) && bf->flag != 0;
|
||||
bf++) {
|
||||
if (strcmp(bf->name, allow_name) == 0) {
|
||||
vfsp->vfc_prison_flag = bf->flag;
|
||||
allow_flag = bf->flag;
|
||||
goto no_add;
|
||||
}
|
||||
}
|
||||
@ -3798,7 +3804,7 @@ prison_add_vfs(struct vfsconf *vfsp)
|
||||
/*
|
||||
* Find a free bit in prison0's pr_allow, failing if there are none
|
||||
* (which shouldn't happen as long as we keep track of how many
|
||||
* filesystems are jail-aware).
|
||||
* potential dynamic flags exist).
|
||||
*/
|
||||
for (allow_flag = 1;; allow_flag <<= 1) {
|
||||
if (allow_flag == 0)
|
||||
@ -3815,52 +3821,73 @@ prison_add_vfs(struct vfsconf *vfsp)
|
||||
for (bf = pr_flag_allow; bf->flag != 0; bf++)
|
||||
if (bf == pr_flag_allow + nitems(pr_flag_allow)) {
|
||||
/* This should never happen, but is not fatal. */
|
||||
allow_flag = 0;
|
||||
goto no_add;
|
||||
}
|
||||
prison0.pr_allow |= allow_flag;
|
||||
bf->name = allow_name;
|
||||
bf->noname = allow_noname;
|
||||
bf->flag = allow_flag;
|
||||
vfsp->vfc_prison_flag = allow_flag;
|
||||
mtx_unlock(&prison0.pr_mtx);
|
||||
|
||||
/*
|
||||
* Create sysctls for the paramter, and the back-compat global
|
||||
* permission.
|
||||
*/
|
||||
#ifndef NO_SYSCTL_DESCR
|
||||
(void)asprintf(&descr, M_TEMP, "Jail may mount the %s file system",
|
||||
vfsp->vfc_name);
|
||||
#endif
|
||||
(void)SYSCTL_ADD_PROC(NULL,
|
||||
SYSCTL_CHILDREN(&sysctl___security_jail_param_allow_mount),
|
||||
OID_AUTO, vfsp->vfc_name, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
|
||||
parent = prefix
|
||||
? SYSCTL_ADD_NODE(NULL,
|
||||
SYSCTL_CHILDREN(&sysctl___security_jail_param_allow),
|
||||
OID_AUTO, prefix, 0, 0, prefix_descr)
|
||||
: &sysctl___security_jail_param_allow;
|
||||
(void)SYSCTL_ADD_PROC(NULL, SYSCTL_CHILDREN(parent), OID_AUTO,
|
||||
name, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
|
||||
NULL, 0, sysctl_jail_param, "B", descr);
|
||||
if ((prefix
|
||||
? asprintf(&allowed, M_TEMP, "%s_%s_allowed", prefix, name)
|
||||
: asprintf(&allowed, M_TEMP, "%s_allowed", name)) >= 0) {
|
||||
#ifndef NO_SYSCTL_DESCR
|
||||
free(descr, M_TEMP);
|
||||
#endif
|
||||
if (asprintf(&mount_allowed, M_TEMP, "mount_%s_allowed",
|
||||
vfsp->vfc_name) >= 0) {
|
||||
#ifndef NO_SYSCTL_DESCR
|
||||
(void)asprintf(&descr, M_TEMP,
|
||||
"Processes in jail can mount the %s file system (deprecated)",
|
||||
vfsp->vfc_name);
|
||||
(void)asprintf(&descr_deprecated, M_TEMP, "%s (deprecated)",
|
||||
descr);
|
||||
#endif
|
||||
(void)SYSCTL_ADD_PROC(NULL,
|
||||
SYSCTL_CHILDREN(&sysctl___security_jail), OID_AUTO,
|
||||
mount_allowed, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
|
||||
NULL, allow_flag, sysctl_jail_default_allow, "I", descr);
|
||||
SYSCTL_CHILDREN(&sysctl___security_jail), OID_AUTO, allowed,
|
||||
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, allow_flag,
|
||||
sysctl_jail_default_allow, "I", descr_deprecated);
|
||||
#ifndef NO_SYSCTL_DESCR
|
||||
free(descr, M_TEMP);
|
||||
free(descr_deprecated, M_TEMP);
|
||||
#endif
|
||||
free(mount_allowed, M_TEMP);
|
||||
free(allowed, M_TEMP);
|
||||
}
|
||||
return;
|
||||
return allow_flag;
|
||||
|
||||
no_add:
|
||||
mtx_unlock(&prison0.pr_mtx);
|
||||
free(allow_name, M_PRISON);
|
||||
free(allow_noname, M_PRISON);
|
||||
return allow_flag;
|
||||
}
|
||||
|
||||
/*
|
||||
* The VFS system will register jail-aware filesystems here. They each get
|
||||
* a parameter allow.mount.xxxfs and a flag to check when a jailed user
|
||||
* attempts to mount.
|
||||
*/
|
||||
void
|
||||
prison_add_vfs(struct vfsconf *vfsp)
|
||||
{
|
||||
#ifdef NO_SYSCTL_DESCR
|
||||
|
||||
vfsp->vfc_prison_flag = prison_add_allow("mount", vfsp->vfc_name,
|
||||
NULL, NULL);
|
||||
#else
|
||||
char *descr;
|
||||
|
||||
(void)asprintf(&descr, M_TEMP, "Jail may mount the %s file system",
|
||||
vfsp->vfc_name);
|
||||
vfsp->vfc_prison_flag = prison_add_allow("mount", vfsp->vfc_name,
|
||||
NULL, descr);
|
||||
free(descr, M_TEMP);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef RACCT
|
||||
|
@ -409,6 +409,8 @@ int prison_if(struct ucred *cred, struct sockaddr *sa);
|
||||
char *prison_name(struct prison *, struct prison *);
|
||||
int prison_priv_check(struct ucred *cred, int priv);
|
||||
int sysctl_jail_param(SYSCTL_HANDLER_ARGS);
|
||||
unsigned prison_add_allow(const char *prefix, const char *name,
|
||||
const char *prefix_descr, const char *descr);
|
||||
void prison_add_vfs(struct vfsconf *vfsp);
|
||||
void prison_racct_foreach(void (*callback)(struct racct *racct,
|
||||
void *arg2, void *arg3), void (*pre)(void), void (*post)(void),
|
||||
|
Loading…
Reference in New Issue
Block a user