svn commit: r286021 - in head/sys: compat/cloudabi compat/linux kern sys

Ed Schouten ed at FreeBSD.org
Wed Jul 29 17:18:30 UTC 2015


Author: ed
Date: Wed Jul 29 17:18:27 2015
New Revision: 286021
URL: https://svnweb.freebsd.org/changeset/base/286021

Log:
  Make pipes in CloudABI work.
  
  Summary:
  Pipes in CloudABI are unidirectional. The reason for this is that
  CloudABI attempts to provide a uniform runtime environment across
  different flavours of UNIX.
  
  Instead of implementing a custom pipe that is unidirectional, we can
  simply reuse Capsicum permission bits to support this. This is nice,
  because CloudABI already attempts to restrict permission bits to
  correspond with the operations that apply to a certain file descriptor.
  
  Replace kern_pipe() and kern_pipe2() by a single kern_pipe() that takes
  a pair of filecaps. These filecaps are passed to the newly introduced
  falloc_caps() function that creates the descriptors with rights in
  place.
  
  Test Plan:
  CloudABI pipes seem to be created with proper rights in place:
  
  https://github.com/NuxiNL/cloudlibc/blob/master/src/libc/unistd/pipe_test.c#L44
  
  Reviewers: jilles, mjg
  
  Reviewed By: mjg
  
  Subscribers: imp
  
  Differential Revision: https://reviews.freebsd.org/D3236

Modified:
  head/sys/compat/cloudabi/cloudabi_fd.c
  head/sys/compat/linux/linux_file.c
  head/sys/kern/sys_pipe.c
  head/sys/sys/syscallsubr.h

Modified: head/sys/compat/cloudabi/cloudabi_fd.c
==============================================================================
--- head/sys/compat/cloudabi/cloudabi_fd.c	Wed Jul 29 17:16:53 2015	(r286020)
+++ head/sys/compat/cloudabi/cloudabi_fd.c	Wed Jul 29 17:18:27 2015	(r286021)
@@ -120,10 +120,24 @@ int
 cloudabi_sys_fd_create2(struct thread *td,
     struct cloudabi_sys_fd_create2_args *uap)
 {
+	struct filecaps fcaps1 = {}, fcaps2 = {};
 	int fds[2];
 	int error;
 
 	switch (uap->type) {
+	case CLOUDABI_FILETYPE_FIFO:
+		/*
+		 * CloudABI pipes are unidirectional. Restrict rights on
+		 * the pipe to simulate this.
+		 */
+		cap_rights_init(&fcaps1.fc_rights, CAP_EVENT, CAP_FCNTL,
+		    CAP_FSTAT, CAP_READ);
+		fcaps1.fc_fcntls = CAP_FCNTL_SETFL;
+		cap_rights_init(&fcaps2.fc_rights, CAP_EVENT, CAP_FCNTL,
+		    CAP_FSTAT, CAP_WRITE);
+		fcaps2.fc_fcntls = CAP_FCNTL_SETFL;
+		error = kern_pipe(td, fds, 0, &fcaps1, &fcaps2);
+		break;
 	case CLOUDABI_FILETYPE_SOCKET_DGRAM:
 		error = kern_socketpair(td, AF_UNIX, SOCK_DGRAM, 0, fds);
 		break;

Modified: head/sys/compat/linux/linux_file.c
==============================================================================
--- head/sys/compat/linux/linux_file.c	Wed Jul 29 17:16:53 2015	(r286020)
+++ head/sys/compat/linux/linux_file.c	Wed Jul 29 17:18:27 2015	(r286021)
@@ -1582,7 +1582,7 @@ linux_pipe(struct thread *td, struct lin
 		printf(ARGS(pipe, "*"));
 #endif
 
-	error = kern_pipe2(td, fildes, 0);
+	error = kern_pipe(td, fildes, 0, NULL, NULL);
 	if (error)
 		return (error);
 
@@ -1609,7 +1609,7 @@ linux_pipe2(struct thread *td, struct li
 		flags |= O_NONBLOCK;
 	if ((args->flags & LINUX_O_CLOEXEC) != 0)
 		flags |= O_CLOEXEC;
-	error = kern_pipe2(td, fildes, flags);
+	error = kern_pipe(td, fildes, flags, NULL, NULL);
 	if (error)
 		return (error);
 

Modified: head/sys/kern/sys_pipe.c
==============================================================================
--- head/sys/kern/sys_pipe.c	Wed Jul 29 17:16:53 2015	(r286020)
+++ head/sys/kern/sys_pipe.c	Wed Jul 29 17:18:27 2015	(r286021)
@@ -397,14 +397,8 @@ pipe_dtor(struct pipe *dpipe)
  * the zone pick up the pieces via pipeclose().
  */
 int
-kern_pipe(struct thread *td, int fildes[2])
-{
-
-	return (kern_pipe2(td, fildes, 0));
-}
-
-int
-kern_pipe2(struct thread *td, int fildes[2], int flags)
+kern_pipe(struct thread *td, int fildes[2], int flags, struct filecaps *fcaps1,
+    struct filecaps *fcaps2)
 {
 	struct file *rf, *wf;
 	struct pipe *rpipe, *wpipe;
@@ -414,13 +408,13 @@ kern_pipe2(struct thread *td, int fildes
 	pipe_paircreate(td, &pp);
 	rpipe = &pp->pp_rpipe;
 	wpipe = &pp->pp_wpipe;
-	error = falloc(td, &rf, &fd, flags);
+	error = falloc_caps(td, &rf, &fd, flags, fcaps1);
 	if (error) {
 		pipeclose(rpipe);
 		pipeclose(wpipe);
 		return (error);
 	}
-	/* An extra reference on `rf' has been held for us by falloc(). */
+	/* An extra reference on `rf' has been held for us by falloc_caps(). */
 	fildes[0] = fd;
 
 	fflags = FREAD | FWRITE;
@@ -434,7 +428,7 @@ kern_pipe2(struct thread *td, int fildes
 	 * side while we are blocked trying to allocate the write side.
 	 */
 	finit(rf, fflags, DTYPE_PIPE, rpipe, &pipeops);
-	error = falloc(td, &wf, &fd, flags);
+	error = falloc_caps(td, &wf, &fd, flags, fcaps2);
 	if (error) {
 		fdclose(td, rf, fildes[0]);
 		fdrop(rf, td);
@@ -442,7 +436,7 @@ kern_pipe2(struct thread *td, int fildes
 		pipeclose(wpipe);
 		return (error);
 	}
-	/* An extra reference on `wf' has been held for us by falloc(). */
+	/* An extra reference on `wf' has been held for us by falloc_caps(). */
 	finit(wf, fflags, DTYPE_PIPE, wpipe, &pipeops);
 	fdrop(wf, td);
 	fildes[1] = fd;
@@ -458,7 +452,7 @@ sys_pipe(struct thread *td, struct pipe_
 	int error;
 	int fildes[2];
 
-	error = kern_pipe(td, fildes);
+	error = kern_pipe(td, fildes, 0, NULL, NULL);
 	if (error)
 		return (error);
 
@@ -475,7 +469,7 @@ sys_pipe2(struct thread *td, struct pipe
 
 	if (uap->flags & ~(O_CLOEXEC | O_NONBLOCK))
 		return (EINVAL);
-	error = kern_pipe2(td, fildes, uap->flags);
+	error = kern_pipe(td, fildes, uap->flags, NULL, NULL);
 	if (error)
 		return (error);
 	error = copyout(fildes, uap->fildes, 2 * sizeof(int));

Modified: head/sys/sys/syscallsubr.h
==============================================================================
--- head/sys/sys/syscallsubr.h	Wed Jul 29 17:16:53 2015	(r286020)
+++ head/sys/sys/syscallsubr.h	Wed Jul 29 17:18:27 2015	(r286021)
@@ -35,6 +35,7 @@
 #include <sys/mount.h>
 
 struct file;
+struct filecaps;
 enum idtype;
 struct itimerval;
 struct image_args;
@@ -150,8 +151,8 @@ int	kern_openat(struct thread *td, int f
 	    enum uio_seg pathseg, int flags, int mode);
 int	kern_pathconf(struct thread *td, char *path, enum uio_seg pathseg,
 	    int name, u_long flags);
-int	kern_pipe(struct thread *td, int fildes[2]);
-int	kern_pipe2(struct thread *td, int fildes[2], int flags);
+int	kern_pipe(struct thread *td, int fildes[2], int flags,
+	    struct filecaps *fcaps1, struct filecaps *fcaps2);
 int	kern_poll(struct thread *td, struct pollfd *fds, u_int nfds,
 	    struct timespec *tsp, sigset_t *uset);
 int	kern_posix_fadvise(struct thread *td, int fd, off_t offset, off_t len,


More information about the svn-src-head mailing list