summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_jail.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/kern_jail.c')
-rw-r--r--sys/kern/kern_jail.c50
1 files changed, 31 insertions, 19 deletions
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index 84f5575..de92dc4 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -531,6 +531,7 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
int gotchildmax, gotenforce, gothid, gotslevel;
int fi, jid, jsys, len, level;
int childmax, slevel, vfslocked;
+ int fullpath_disabled;
#if defined(INET) || defined(INET6)
int ii, ij;
#endif
@@ -897,30 +898,40 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
error = EINVAL;
goto done_free;
}
- if (len < 2 || (len == 2 && path[0] == '/'))
- path = NULL;
- else {
+ NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE, UIO_SYSSPACE,
+ path, td);
+ error = namei(&nd);
+ if (error)
+ goto done_free;
+ vfslocked = NDHASGIANT(&nd);
+ root = nd.ni_vp;
+ NDFREE(&nd, NDF_ONLY_PNBUF);
+ error = vn_path_to_global_path(td, root, path, MAXPATHLEN);
+ if (error == ENODEV) {
+ /* proceed if sysctl debug.disablefullpath == 1 */
+ fullpath_disabled = 1;
+ if (len < 2 || (len == 2 && path[0] == '/'))
+ path = NULL;
+ } else if (error != 0) {
+ /* exit on other errors */
+ VFS_UNLOCK_GIANT(vfslocked);
+ goto done_free;
+ }
+ if (root->v_type != VDIR) {
+ error = ENOTDIR;
+ vput(root);
+ VFS_UNLOCK_GIANT(vfslocked);
+ goto done_free;
+ }
+ VOP_UNLOCK(root, 0);
+ VFS_UNLOCK_GIANT(vfslocked);
+ if (fullpath_disabled) {
/* Leave room for a real-root full pathname. */
if (len + (path[0] == '/' && strcmp(mypr->pr_path, "/")
? strlen(mypr->pr_path) : 0) > MAXPATHLEN) {
error = ENAMETOOLONG;
goto done_free;
}
- NDINIT(&nd, LOOKUP, MPSAFE | FOLLOW, UIO_SYSSPACE,
- path, td);
- error = namei(&nd);
- if (error)
- goto done_free;
- vfslocked = NDHASGIANT(&nd);
- root = nd.ni_vp;
- NDFREE(&nd, NDF_ONLY_PNBUF);
- if (root->v_type != VDIR) {
- error = ENOTDIR;
- vrele(root);
- VFS_UNLOCK_GIANT(vfslocked);
- goto done_free;
- }
- VFS_UNLOCK_GIANT(vfslocked);
}
}
@@ -1583,7 +1594,8 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
}
if (path != NULL) {
/* Try to keep a real-rooted full pathname. */
- if (path[0] == '/' && strcmp(mypr->pr_path, "/"))
+ if (fullpath_disabled && path[0] == '/' &&
+ strcmp(mypr->pr_path, "/"))
snprintf(pr->pr_path, sizeof(pr->pr_path), "%s%s",
mypr->pr_path, path);
else
OpenPOWER on IntegriCloud