From owner-svn-src-head@freebsd.org Wed Sep 25 17:35:04 2019 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 407B912E120; Wed, 25 Sep 2019 17:35:04 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 46dlZ00zplz4DR2; Wed, 25 Sep 2019 17:35:04 +0000 (UTC) (envelope-from kevans@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 mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id DBDA91B287; Wed, 25 Sep 2019 17:35:03 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x8PHZ3A7064709; Wed, 25 Sep 2019 17:35:03 GMT (envelope-from kevans@FreeBSD.org) Received: (from kevans@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x8PHZ34q064707; Wed, 25 Sep 2019 17:35:03 GMT (envelope-from kevans@FreeBSD.org) Message-Id: <201909251735.x8PHZ34q064707@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kevans set sender to kevans@FreeBSD.org using -f From: Kyle Evans Date: Wed, 25 Sep 2019 17:35:03 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r352697 - in head/sys: compat/cloudabi kern sys X-SVN-Group: head X-SVN-Commit-Author: kevans X-SVN-Commit-Paths: in head/sys: compat/cloudabi kern sys X-SVN-Commit-Revision: 352697 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 25 Sep 2019 17:35:04 -0000 Author: kevans Date: Wed Sep 25 17:35:03 2019 New Revision: 352697 URL: https://svnweb.freebsd.org/changeset/base/352697 Log: [2/3] Add an initial seal argument to kern_shm_open() Now that flags may be set on posixshm, add an argument to kern_shm_open() for the initial seals. To maintain past behavior where callers of shm_open(2) are guaranteed to not have any seals applied to the fd they're given, apply F_SEAL_SEAL for existing callers of kern_shm_open. A special flag could be opened later for shm_open(2) to indicate that sealing should be allowed. We currently restrict initial seals to F_SEAL_SEAL. We cannot error out if F_SEAL_SEAL is re-applied, as this would easily break shm_open() twice to a shmfd that already existed. A note's been added about the assumptions we've made here as a hint towards anyone wanting to allow other seals to be applied at creation. Reviewed by: kib, markj Differential Revision: https://reviews.freebsd.org/D21392 Modified: head/sys/compat/cloudabi/cloudabi_fd.c head/sys/kern/uipc_shm.c head/sys/sys/syscallsubr.h Modified: head/sys/compat/cloudabi/cloudabi_fd.c ============================================================================== --- head/sys/compat/cloudabi/cloudabi_fd.c Wed Sep 25 17:33:12 2019 (r352696) +++ head/sys/compat/cloudabi/cloudabi_fd.c Wed Sep 25 17:35:03 2019 (r352697) @@ -28,6 +28,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -95,7 +96,7 @@ cloudabi_sys_fd_create1(struct thread *td, cap_rights_init(&fcaps.fc_rights, CAP_FSTAT, CAP_FTRUNCATE, CAP_MMAP_RWX); return (kern_shm_open(td, SHM_ANON, O_RDWR | O_CLOEXEC, 0, - &fcaps)); + &fcaps, F_SEAL_SEAL)); default: return (EINVAL); } Modified: head/sys/kern/uipc_shm.c ============================================================================== --- head/sys/kern/uipc_shm.c Wed Sep 25 17:33:12 2019 (r352696) +++ head/sys/kern/uipc_shm.c Wed Sep 25 17:35:03 2019 (r352697) @@ -701,13 +701,14 @@ shm_remove(char *path, Fnv32_t fnv, struct ucred *ucre int kern_shm_open(struct thread *td, const char *userpath, int flags, mode_t mode, - struct filecaps *fcaps) + struct filecaps *fcaps, int initial_seals) { struct filedesc *fdp; struct shmfd *shmfd; struct file *fp; char *path; const char *pr_path; + void *rl_cookie; size_t pr_pathlen; Fnv32_t fnv; mode_t cmode; @@ -730,6 +731,17 @@ kern_shm_open(struct thread *td, const char *userpath, if ((flags & ~(O_ACCMODE | O_CREAT | O_EXCL | O_TRUNC | O_CLOEXEC)) != 0) return (EINVAL); + /* + * Currently only F_SEAL_SEAL may be set when creating or opening shmfd. + * If the decision is made later to allow additional seals, care must be + * taken below to ensure that the seals are properly set if the shmfd + * already existed -- this currently assumes that only F_SEAL_SEAL can + * be set and doesn't take further precautions to ensure the validity of + * the seals being added with respect to current mappings. + */ + if ((initial_seals & ~F_SEAL_SEAL) != 0) + return (EINVAL); + fdp = td->td_proc->p_fd; cmode = (mode & ~fdp->fd_cmask) & ACCESSPERMS; @@ -753,6 +765,7 @@ kern_shm_open(struct thread *td, const char *userpath, return (EINVAL); } shmfd = shm_alloc(td->td_ucred, cmode); + shmfd->shm_seals = initial_seals; } else { path = malloc(MAXPATHLEN, M_SHMFD, M_WAITOK); pr_path = td->td_ucred->cr_prison->pr_path; @@ -789,6 +802,7 @@ kern_shm_open(struct thread *td, const char *userpath, if (error == 0) { #endif shmfd = shm_alloc(td->td_ucred, cmode); + shmfd->shm_seals = initial_seals; shm_insert(path, fnv, shmfd); #ifdef MAC } @@ -798,12 +812,39 @@ kern_shm_open(struct thread *td, const char *userpath, error = ENOENT; } } else { + rl_cookie = rangelock_wlock(&shmfd->shm_rl, 0, OFF_MAX, + &shmfd->shm_mtx); + /* + * kern_shm_open() likely shouldn't ever error out on + * trying to set a seal that already exists, unlike + * F_ADD_SEALS. This would break terribly as + * shm_open(2) actually sets F_SEAL_SEAL to maintain + * historical behavior where the underlying file could + * not be sealed. + */ + initial_seals &= ~shmfd->shm_seals; + + /* * Object already exists, obtain a new * reference if requested and permitted. */ free(path, M_SHMFD); - if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) + + /* + * initial_seals can't set additional seals if we've + * already been set F_SEAL_SEAL. If F_SEAL_SEAL is set, + * then we've already removed that one from + * initial_seals. This is currently redundant as we + * only allow setting F_SEAL_SEAL at creation time, but + * it's cheap to check and decreases the effort required + * to allow additional seals. + */ + if ((shmfd->shm_seals & F_SEAL_SEAL) != 0 && + initial_seals != 0) + error = EPERM; + else if ((flags & (O_CREAT | O_EXCL)) == + (O_CREAT | O_EXCL)) error = EEXIST; else { #ifdef MAC @@ -823,15 +864,27 @@ kern_shm_open(struct thread *td, const char *userpath, if (error == 0 && (flags & (O_ACCMODE | O_TRUNC)) == (O_RDWR | O_TRUNC)) { + VM_OBJECT_WLOCK(shmfd->shm_object); #ifdef MAC error = mac_posixshm_check_truncate( td->td_ucred, fp->f_cred, shmfd); if (error == 0) #endif - shm_dotruncate(shmfd, 0); + error = shm_dotruncate_locked(shmfd, 0, + rl_cookie); + VM_OBJECT_WUNLOCK(shmfd->shm_object); } - if (error == 0) + if (error == 0) { + /* + * Currently we only allow F_SEAL_SEAL to be + * set initially. As noted above, this would + * need to be reworked should that change. + */ + shmfd->shm_seals |= initial_seals; shm_hold(shmfd); + } + rangelock_unlock(&shmfd->shm_rl, rl_cookie, + &shmfd->shm_mtx); } sx_xunlock(&shm_dict_lock); @@ -856,7 +909,7 @@ sys_shm_open(struct thread *td, struct shm_open_args * { return (kern_shm_open(td, uap->path, uap->flags | O_CLOEXEC, uap->mode, - NULL)); + NULL, F_SEAL_SEAL)); } int Modified: head/sys/sys/syscallsubr.h ============================================================================== --- head/sys/sys/syscallsubr.h Wed Sep 25 17:33:12 2019 (r352696) +++ head/sys/sys/syscallsubr.h Wed Sep 25 17:35:03 2019 (r352697) @@ -250,7 +250,7 @@ int kern_setsockopt(struct thread *td, int s, int leve int kern_settimeofday(struct thread *td, struct timeval *tv, struct timezone *tzp); int kern_shm_open(struct thread *td, const char *userpath, int flags, - mode_t mode, struct filecaps *fcaps); + mode_t mode, struct filecaps *fcaps, int initial_seals); int kern_shmat(struct thread *td, int shmid, const void *shmaddr, int shmflg); int kern_shmctl(struct thread *td, int shmid, int cmd, void *buf,