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 <sys/param.h>
+#include <sys/capsicum.h>
+#include <sys/filedesc.h>
 #include <sys/imgact.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
@@ -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 *);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to