svn commit: r359132 - head/sys/kern

Mark Johnston markj at FreeBSD.org
Thu Mar 19 15:39:46 UTC 2020


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);


More information about the svn-src-all mailing list