Author: jamie Date: Wed Apr 13 20:14:13 2016 New Revision: 297935 URL: https://svnweb.freebsd.org/changeset/base/297935
Log: Separate POSIX sem/shm objects in jails, by prepending the jail's path name to the object's "path". While the objects don't have real path names, it's a filesystem-like namespace, which allows jails to be kept to their own space, but still allows the system / jail parent to access a jail's IPC. PR: 208082 Modified: head/sys/kern/uipc_sem.c head/sys/kern/uipc_shm.c Modified: head/sys/kern/uipc_sem.c ============================================================================== --- head/sys/kern/uipc_sem.c Wed Apr 13 20:12:02 2016 (r297934) +++ head/sys/kern/uipc_sem.c Wed Apr 13 20:14:13 2016 (r297935) @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include <sys/file.h> #include <sys/filedesc.h> #include <sys/fnv_hash.h> +#include <sys/jail.h> #include <sys/kernel.h> #include <sys/ksem.h> #include <sys/lock.h> @@ -258,7 +259,9 @@ ksem_closef(struct file *fp, struct thre static int ksem_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp) { + const char *path, *pr_path; struct ksem *ks; + size_t pr_pathlen; kif->kf_type = KF_TYPE_SEM; ks = fp->f_data; @@ -269,7 +272,19 @@ ksem_fill_kinfo(struct file *fp, struct if (ks->ks_path != NULL) { sx_slock(&ksem_dict_lock); if (ks->ks_path != NULL) - strlcpy(kif->kf_path, ks->ks_path, sizeof(kif->kf_path)); + { + path = ks->ks_path; + pr_path = curthread->td_ucred->cr_prison->pr_path; + if (strcmp(pr_path, "/") != 0) + { + /* Return the jail-rooted pathname */ + pr_pathlen = strlen(pr_path); + if (strncmp(path, pr_path, pr_pathlen) == 0 && + path[pr_pathlen] == '/') + path += pr_pathlen; + } + strlcpy(kif->kf_path, path, sizeof(kif->kf_path)); + } sx_sunlock(&ksem_dict_lock); } return (0); @@ -449,6 +464,8 @@ ksem_create(struct thread *td, const cha struct ksem *ks; struct file *fp; char *path; + const char *pr_path; + size_t pr_pathlen; Fnv32_t fnv; int error, fd; @@ -485,10 +502,15 @@ ksem_create(struct thread *td, const cha ks->ks_flags |= KS_ANONYMOUS; } else { path = malloc(MAXPATHLEN, M_KSEM, M_WAITOK); - error = copyinstr(name, path, MAXPATHLEN, NULL); + pr_path = td->td_ucred->cr_prison->pr_path; + /* Construct a full pathname for jailed callers */ + pr_pathlen = strcmp(pr_path, "/") == 0 ? 0 + : strlcpy(path, pr_path, MAXPATHLEN); + error = copyinstr(name, path + pr_pathlen, + MAXPATHLEN - pr_pathlen, NULL); /* Require paths to start with a '/' character. */ - if (error == 0 && path[0] != '/') + if (error == 0 && path[pr_pathlen] != '/') error = EINVAL; if (error) { fdclose(td, fp, fd); @@ -624,11 +646,17 @@ int sys_ksem_unlink(struct thread *td, struct ksem_unlink_args *uap) { char *path; + const char *pr_path; + size_t pr_pathlen; Fnv32_t fnv; int error; path = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); - error = copyinstr(uap->name, path, MAXPATHLEN, NULL); + pr_path = td->td_ucred->cr_prison->pr_path; + pr_pathlen = strcmp(pr_path, "/") == 0 ? 0 + : strlcpy(path, pr_path, MAXPATHLEN); + error = copyinstr(uap->name, path + pr_pathlen, MAXPATHLEN - pr_pathlen, + NULL); if (error) { free(path, M_TEMP); return (error); Modified: head/sys/kern/uipc_shm.c ============================================================================== --- head/sys/kern/uipc_shm.c Wed Apr 13 20:12:02 2016 (r297934) +++ head/sys/kern/uipc_shm.c Wed Apr 13 20:14:13 2016 (r297935) @@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$"); #include <sys/kernel.h> #include <sys/uio.h> #include <sys/signal.h> +#include <sys/jail.h> #include <sys/ktrace.h> #include <sys/lock.h> #include <sys/malloc.h> @@ -687,6 +688,8 @@ kern_shm_open(struct thread *td, const c struct shmfd *shmfd; struct file *fp; char *path; + const char *pr_path; + size_t pr_pathlen; Fnv32_t fnv; mode_t cmode; int fd, error; @@ -723,13 +726,18 @@ kern_shm_open(struct thread *td, const c shmfd = shm_alloc(td->td_ucred, cmode); } else { path = malloc(MAXPATHLEN, M_SHMFD, M_WAITOK); - error = copyinstr(userpath, path, MAXPATHLEN, NULL); + pr_path = td->td_ucred->cr_prison->pr_path; + /* Construct a full pathname for jailed callers */ + pr_pathlen = strcmp(pr_path, "/") == 0 ? 0 + : strlcpy(path, pr_path, MAXPATHLEN); + error = copyinstr(userpath, path + pr_pathlen, + MAXPATHLEN - pr_pathlen, NULL); #ifdef KTRACE if (error == 0 && KTRPOINT(curthread, KTR_NAMEI)) ktrnamei(path); #endif /* Require paths to start with a '/' character. */ - if (error == 0 && path[0] != '/') + if (error == 0 && path[pr_pathlen] != '/') error = EINVAL; if (error) { fdclose(td, fp, fd); @@ -823,11 +831,17 @@ int sys_shm_unlink(struct thread *td, struct shm_unlink_args *uap) { char *path; + const char *pr_path; + size_t pr_pathlen; Fnv32_t fnv; int error; path = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); - error = copyinstr(uap->path, path, MAXPATHLEN, NULL); + pr_path = td->td_ucred->cr_prison->pr_path; + pr_pathlen = strcmp(pr_path, "/") == 0 ? 0 + : strlcpy(path, pr_path, MAXPATHLEN); + error = copyinstr(uap->path, path + pr_pathlen, MAXPATHLEN - pr_pathlen, + NULL); if (error) { free(path, M_TEMP); return (error); @@ -1060,7 +1074,9 @@ shm_unmap(struct file *fp, void *mem, si static int shm_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp) { + const char *path, *pr_path; struct shmfd *shmfd; + size_t pr_pathlen; kif->kf_type = KF_TYPE_SHM; shmfd = fp->f_data; @@ -1072,8 +1088,19 @@ shm_fill_kinfo(struct file *fp, struct k if (shmfd->shm_path != NULL) { sx_slock(&shm_dict_lock); if (shmfd->shm_path != NULL) - strlcpy(kif->kf_path, shmfd->shm_path, - sizeof(kif->kf_path)); + { + path = shmfd->shm_path; + pr_path = curthread->td_ucred->cr_prison->pr_path; + if (strcmp(pr_path, "/") != 0) + { + /* Return the jail-rooted pathname */ + pr_pathlen = strlen(pr_path); + if (strncmp(path, pr_path, pr_pathlen) == 0 && + path[pr_pathlen] == '/') + path += pr_pathlen; + } + strlcpy(kif->kf_path, path, sizeof(kif->kf_path)); + } sx_sunlock(&shm_dict_lock); } return (0); _______________________________________________ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"