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
This commit is contained in:
parent
a2b3dfad08
commit
367a13f905
@ -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. */
|
||||
|
@ -73,8 +73,8 @@ linux_fork(struct thread *td, struct linux_fork_args *args)
|
||||
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 linux_vfork_args *args)
|
||||
|
||||
/* 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, struct linux_clone_args *args)
|
||||
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);
|
||||
|
||||
|
@ -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"));
|
||||
|
@ -104,7 +104,7 @@ sys_fork(struct thread *td, struct fork_args *uap)
|
||||
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 vfork_args *uap)
|
||||
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 rfork_args *uap)
|
||||
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, struct proc *p2, struct thread *td2,
|
||||
|
||||
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 pages, struct proc **procp,
|
||||
* 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);
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ kproc_create(void (*func)(void *), void *arg,
|
||||
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;
|
||||
|
||||
|
@ -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, struct pgrp *pgrp,
|
||||
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 *);
|
||||
|
Loading…
Reference in New Issue
Block a user