Date: Thu, 19 Mar 2020 15:39:45 +0000 (UTC) From: Mark Johnston <markj@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r359132 - head/sys/kern Message-ID: <202003191539.02JFdjlH082092@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: markj Date: Thu Mar 19 15:39:45 2020 New Revision: 359132 URL: https://svnweb.freebsd.org/changeset/base/359132 Log: Enter a write sequence when updating rights. The Capsicum system calls modify file descriptor table entries. To ensure that readers observe a consistent snapshot of descriptor writes, the system calls need to signal to unlocked readers that an update is pending. Note that ioctl rights are always checked with the descriptor table lock held, so it is not strictly necessary to signal unlocked readers. However, we probably want to enable lockless ioctl checks eventually, so use seqc_write_begin() in kern_cap_ioctls_limit() too. Reviewed by: kib MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D24119 Modified: head/sys/kern/sys_capability.c Modified: head/sys/kern/sys_capability.c ============================================================================== --- head/sys/kern/sys_capability.c Thu Mar 19 14:37:28 2020 (r359131) +++ head/sys/kern/sys_capability.c Thu Mar 19 15:39:45 2020 (r359132) @@ -234,6 +234,7 @@ kern_cap_rights_limit(struct thread *td, int fd, cap_r { struct filedesc *fdp; struct filedescent *fdep; + u_long *ioctls; int error; fdp = td->td_proc->p_fd; @@ -243,18 +244,22 @@ kern_cap_rights_limit(struct thread *td, int fd, cap_r FILEDESC_XUNLOCK(fdp); return (EBADF); } + ioctls = NULL; error = _cap_check(cap_rights(fdp, fd), rights, CAPFAIL_INCREASE); if (error == 0) { + seqc_write_begin(&fdep->fde_seqc); fdep->fde_rights = *rights; if (!cap_rights_is_set(rights, CAP_IOCTL)) { - free(fdep->fde_ioctls, M_FILECAPS); + ioctls = fdep->fde_ioctls; fdep->fde_ioctls = NULL; fdep->fde_nioctls = 0; } if (!cap_rights_is_set(rights, CAP_FCNTL)) fdep->fde_fcntls = 0; + seqc_write_end(&fdep->fde_seqc); } FILEDESC_XUNLOCK(fdp); + free(ioctls, M_FILECAPS); return (error); } @@ -439,8 +444,10 @@ kern_cap_ioctls_limit(struct thread *td, int fd, u_lon goto out; ocmds = fdep->fde_ioctls; + seqc_write_begin(&fdep->fde_seqc); fdep->fde_ioctls = cmds; fdep->fde_nioctls = ncmds; + seqc_write_end(&fdep->fde_seqc); cmds = ocmds; error = 0; @@ -597,7 +604,9 @@ sys_cap_fcntls_limit(struct thread *td, struct cap_fcn return (ENOTCAPABLE); } + seqc_write_begin(&fdep->fde_seqc); fdep->fde_fcntls = fcntlrights; + seqc_write_end(&fdep->fde_seqc); FILEDESC_XUNLOCK(fdp); return (0);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202003191539.02JFdjlH082092>