From owner-svn-src-all@freebsd.org Fri Jul 31 10:22:01 2015 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C746A9AF759; Fri, 31 Jul 2015 10:22:01 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id B7A801AD7; Fri, 31 Jul 2015 10:22:01 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.14.9/8.14.9) with ESMTP id t6VAM1wk056185; Fri, 31 Jul 2015 10:22:01 GMT (envelope-from ed@FreeBSD.org) Received: (from ed@localhost) by repo.freebsd.org (8.14.9/8.14.9/Submit) id t6VALx1J056150; Fri, 31 Jul 2015 10:21:59 GMT (envelope-from ed@FreeBSD.org) Message-Id: <201507311021.t6VALx1J056150@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ed set sender to ed@FreeBSD.org using -f From: Ed Schouten Date: Fri, 31 Jul 2015 10:21:59 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r286122 - in head/sys: compat/cloudabi compat/linux kern sys X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 31 Jul 2015 10:22:01 -0000 Author: ed Date: Fri Jul 31 10:21:58 2015 New Revision: 286122 URL: https://svnweb.freebsd.org/changeset/base/286122 Log: Limit rights on process descriptors. On CloudABI, the rights bits returned by cap_rights_get() match up with the operations that you can actually perform on the file descriptor. Limiting the rights is good, because it makes it easier to get uniform behaviour across different operating systems. If process descriptors on FreeBSD would suddenly gain support for any new file operation, this wouldn't become exposed to CloudABI processes without first extending the rights. Extend fork1() to gain a 'struct filecaps' argument that allows you to construct process descriptors with custom rights. Use this in cloudabi_sys_proc_fork() to limit the rights to just fstat() and pdwait(). Obtained from: https://github.com/NuxiNL/freebsd Modified: head/sys/compat/cloudabi/cloudabi_proc.c head/sys/compat/linux/linux_fork.c head/sys/kern/init_main.c head/sys/kern/kern_fork.c head/sys/kern/kern_kthread.c head/sys/sys/proc.h Modified: head/sys/compat/cloudabi/cloudabi_proc.c ============================================================================== --- head/sys/compat/cloudabi/cloudabi_proc.c Fri Jul 31 10:00:45 2015 (r286121) +++ head/sys/compat/cloudabi/cloudabi_proc.c Fri Jul 31 10:21:58 2015 (r286122) @@ -27,6 +27,8 @@ __FBSDID("$FreeBSD$"); #include +#include +#include #include #include #include @@ -67,10 +69,12 @@ int cloudabi_sys_proc_fork(struct thread *td, struct cloudabi_sys_proc_fork_args *uap) { + struct filecaps fcaps = {}; struct proc *p2; int error, fd; - error = fork1(td, RFFDG | RFPROC | RFPROCDESC, 0, &p2, &fd, 0); + cap_rights_init(&fcaps.fc_rights, CAP_FSTAT, CAP_PDWAIT); + error = fork1(td, RFFDG | RFPROC | RFPROCDESC, 0, &p2, &fd, 0, &fcaps); if (error != 0) return (error); /* Return the file descriptor to the parent process. */ Modified: head/sys/compat/linux/linux_fork.c ============================================================================== --- head/sys/compat/linux/linux_fork.c Fri Jul 31 10:00:45 2015 (r286121) +++ head/sys/compat/linux/linux_fork.c Fri Jul 31 10:21:58 2015 (r286122) @@ -73,8 +73,8 @@ linux_fork(struct thread *td, struct lin printf(ARGS(fork, "")); #endif - if ((error = fork1(td, RFFDG | RFPROC | RFSTOPPED, 0, &p2, NULL, 0)) - != 0) + if ((error = fork1(td, RFFDG | RFPROC | RFSTOPPED, 0, &p2, NULL, 0, + NULL)) != 0) return (error); td2 = FIRST_THREAD_IN_PROC(p2); @@ -108,7 +108,7 @@ linux_vfork(struct thread *td, struct li /* Exclude RFPPWAIT */ if ((error = fork1(td, RFFDG | RFPROC | RFMEM | RFSTOPPED, 0, &p2, - NULL, 0)) != 0) + NULL, 0, NULL)) != 0) return (error); @@ -179,7 +179,7 @@ linux_clone_proc(struct thread *td, stru if (args->parent_tidptr == NULL) return (EINVAL); - error = fork1(td, ff, 0, &p2, NULL, 0); + error = fork1(td, ff, 0, &p2, NULL, 0, NULL); if (error) return (error); Modified: head/sys/kern/init_main.c ============================================================================== --- head/sys/kern/init_main.c Fri Jul 31 10:00:45 2015 (r286121) +++ head/sys/kern/init_main.c Fri Jul 31 10:21:58 2015 (r286122) @@ -831,7 +831,7 @@ create_init(const void *udata __unused) int error; error = fork1(&thread0, RFFDG | RFPROC | RFSTOPPED, 0, &initproc, - NULL, 0); + NULL, 0, NULL); if (error) panic("cannot fork init: %d\n", error); KASSERT(initproc->p_pid == 1, ("create_init: initproc->p_pid != 1")); Modified: head/sys/kern/kern_fork.c ============================================================================== --- head/sys/kern/kern_fork.c Fri Jul 31 10:00:45 2015 (r286121) +++ head/sys/kern/kern_fork.c Fri Jul 31 10:21:58 2015 (r286122) @@ -104,7 +104,7 @@ sys_fork(struct thread *td, struct fork_ int error; struct proc *p2; - error = fork1(td, RFFDG | RFPROC, 0, &p2, NULL, 0); + error = fork1(td, RFFDG | RFPROC, 0, &p2, NULL, 0, NULL); if (error == 0) { td->td_retval[0] = p2->p_pid; td->td_retval[1] = 0; @@ -127,7 +127,7 @@ sys_pdfork(td, uap) * itself from the parent using the return value. */ error = fork1(td, RFFDG | RFPROC | RFPROCDESC, 0, &p2, - &fd, uap->flags); + &fd, uap->flags, NULL); if (error == 0) { td->td_retval[0] = p2->p_pid; td->td_retval[1] = 0; @@ -144,7 +144,7 @@ sys_vfork(struct thread *td, struct vfor struct proc *p2; flags = RFFDG | RFPROC | RFPPWAIT | RFMEM; - error = fork1(td, flags, 0, &p2, NULL, 0); + error = fork1(td, flags, 0, &p2, NULL, 0, NULL); if (error == 0) { td->td_retval[0] = p2->p_pid; td->td_retval[1] = 0; @@ -163,7 +163,7 @@ sys_rfork(struct thread *td, struct rfor return (EINVAL); AUDIT_ARG_FFLAGS(uap->flags); - error = fork1(td, uap->flags, 0, &p2, NULL, 0); + error = fork1(td, uap->flags, 0, &p2, NULL, 0, NULL); if (error == 0) { td->td_retval[0] = p2 ? p2->p_pid : 0; td->td_retval[1] = 0; @@ -768,7 +768,7 @@ do_fork(struct thread *td, int flags, st int fork1(struct thread *td, int flags, int pages, struct proc **procp, - int *procdescp, int pdflags) + int *procdescp, int pdflags, struct filecaps *fcaps) { struct proc *p1; struct proc *newproc; @@ -824,7 +824,8 @@ fork1(struct thread *td, int flags, int * later. */ if (flags & RFPROCDESC) { - error = falloc(td, &fp_procdesc, procdescp, 0); + error = falloc_caps(td, &fp_procdesc, procdescp, 0, + fcaps); if (error != 0) return (error); } Modified: head/sys/kern/kern_kthread.c ============================================================================== --- head/sys/kern/kern_kthread.c Fri Jul 31 10:00:45 2015 (r286121) +++ head/sys/kern/kern_kthread.c Fri Jul 31 10:21:58 2015 (r286122) @@ -89,7 +89,7 @@ kproc_create(void (*func)(void *), void panic("kproc_create called too soon"); error = fork1(&thread0, RFMEM | RFFDG | RFPROC | RFSTOPPED | flags, - pages, &p2, NULL, 0); + pages, &p2, NULL, 0, NULL); if (error) return error; Modified: head/sys/sys/proc.h ============================================================================== --- head/sys/sys/proc.h Fri Jul 31 10:00:45 2015 (r286121) +++ head/sys/sys/proc.h Fri Jul 31 10:21:58 2015 (r286122) @@ -161,6 +161,7 @@ struct pargs { * for write access. */ struct cpuset; +struct filecaps; struct kaioinfo; struct kaudit_record; struct kdtrace_proc; @@ -916,7 +917,8 @@ int enterpgrp(struct proc *p, pid_t pgid int enterthispgrp(struct proc *p, struct pgrp *pgrp); void faultin(struct proc *p); void fixjobc(struct proc *p, struct pgrp *pgrp, int entering); -int fork1(struct thread *, int, int, struct proc **, int *, int); +int fork1(struct thread *, int, int, struct proc **, int *, int, + struct filecaps *); void fork_exit(void (*)(void *, struct trapframe *), void *, struct trapframe *); void fork_return(struct thread *, struct trapframe *);