From owner-svn-src-all@freebsd.org Wed Apr 13 20:14:14 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 4B9E5B0FD63; Wed, 13 Apr 2016 20:14:14 +0000 (UTC) (envelope-from jamie@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 mx1.freebsd.org (Postfix) with ESMTPS id 266331A68; Wed, 13 Apr 2016 20:14:14 +0000 (UTC) (envelope-from jamie@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u3DKEDDV078629; Wed, 13 Apr 2016 20:14:13 GMT (envelope-from jamie@FreeBSD.org) Received: (from jamie@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u3DKEDHv078627; Wed, 13 Apr 2016 20:14:13 GMT (envelope-from jamie@FreeBSD.org) Message-Id: <201604132014.u3DKEDHv078627@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jamie set sender to jamie@FreeBSD.org using -f From: Jamie Gritton Date: Wed, 13 Apr 2016 20:14:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r297935 - head/sys/kern X-SVN-Group: head 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.21 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, 13 Apr 2016 20:14:14 -0000 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 #include #include +#include #include #include #include @@ -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 #include #include +#include #include #include #include @@ -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);