diff --git a/sys/compat/cloudabi/cloudabi_fd.c b/sys/compat/cloudabi/cloudabi_fd.c index 1b3aa0f0ce09..5a58cb312d98 100644 --- a/sys/compat/cloudabi/cloudabi_fd.c +++ b/sys/compat/cloudabi/cloudabi_fd.c @@ -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; diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c index 1e5e37a2db76..489dc1e458dc 100644 --- a/sys/compat/linux/linux_file.c +++ b/sys/compat/linux/linux_file.c @@ -1582,7 +1582,7 @@ linux_pipe(struct thread *td, struct linux_pipe_args *args) 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 linux_pipe2_args *args) 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); diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c index 70e76ad39952..a81c9dee055f 100644 --- a/sys/kern/sys_pipe.c +++ b/sys/kern/sys_pipe.c @@ -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[2], int flags) 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[2], int flags) * 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[2], int flags) 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_args *uap) 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 pipe2_args *uap) 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)); diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h index d22c349bb678..f6f851b60a52 100644 --- a/sys/sys/syscallsubr.h +++ b/sys/sys/syscallsubr.h @@ -35,6 +35,7 @@ #include struct file; +struct filecaps; enum idtype; struct itimerval; struct image_args; @@ -150,8 +151,8 @@ int kern_openat(struct thread *td, int fd, char *path, 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,