diff options
-rw-r--r-- | sys/kern/kern_acct.c | 15 | ||||
-rw-r--r-- | sys/kern/kern_event.c | 26 | ||||
-rw-r--r-- | sys/kern/kern_exec.c | 15 | ||||
-rw-r--r-- | sys/kern/kern_fork.c | 19 | ||||
-rw-r--r-- | sys/kern/kern_jail.c | 18 |
5 files changed, 70 insertions, 23 deletions
diff --git a/sys/kern/kern_acct.c b/sys/kern/kern_acct.c index 9d93224..9a2ebab 100644 --- a/sys/kern/kern_acct.c +++ b/sys/kern/kern_acct.c @@ -106,6 +106,8 @@ SYSCTL_INT(_kern, OID_AUTO, acct_chkfreq, CTLFLAG_RW, /* * Accounting system call. Written based on the specification and * previous implementation done by Mark Tinguely. + * + * MPSAFE */ int acct(a1, uap) @@ -118,10 +120,12 @@ acct(a1, uap) struct nameidata nd; int error, flags; + mtx_lock(&Giant); + /* Make sure that the caller is root. */ error = suser(p); if (error) - return (error); + goto done2; /* * If accounting is to be started to a file, open that file for @@ -133,12 +137,13 @@ acct(a1, uap) flags = FWRITE; error = vn_open(&nd, &flags, 0); if (error) - return (error); + goto done2; NDFREE(&nd, NDF_ONLY_PNBUF); VOP_UNLOCK(nd.ni_vp, 0, p); if (nd.ni_vp->v_type != VREG) { vn_close(nd.ni_vp, FWRITE, p->p_ucred, p); - return (EACCES); + error = EACCES; + goto done2; } } @@ -153,7 +158,7 @@ acct(a1, uap) acctp = savacctp = NULLVP; } if (SCARG(uap, path) == NULL) - return (error); + goto done2; /* * Save the new accounting file vnode, and schedule the new @@ -162,6 +167,8 @@ acct(a1, uap) acctp = nd.ni_vp; callout_init(&acctwatch_callout, 0); acctwatch(NULL); +done2: + mtx_unlock(&Giant); return (error); } diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index 208899c..6f871b6 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -331,17 +331,22 @@ filt_timer(struct knote *kn, long hint) return (kn->kn_data != 0); } +/* + * MPSAFE + */ int kqueue(struct proc *p, struct kqueue_args *uap) { - struct filedesc *fdp = p->p_fd; + struct filedesc *fdp; struct kqueue *kq; struct file *fp; int fd, error; + mtx_lock(&Giant); + fdp = p->p_fd; error = falloc(p, &fp, &fd); if (error) - return (error); + goto done2; fp->f_flag = FREAD | FWRITE; fp->f_type = DTYPE_KQUEUE; fp->f_ops = &kqueueops; @@ -352,6 +357,8 @@ kqueue(struct proc *p, struct kqueue_args *uap) if (fdp->fd_knlistsize < 0) fdp->fd_knlistsize = 0; /* this process has a kq */ kq->kq_fdp = fdp; +done2: + mtx_unlock(&Giant); return (error); } @@ -365,21 +372,27 @@ struct kevent_args { const struct timespec *timeout; }; #endif +/* + * MPSAFE + */ int kevent(struct proc *p, struct kevent_args *uap) { - struct filedesc* fdp = p->p_fd; + struct filedesc *fdp; struct kevent *kevp; struct kqueue *kq; struct file *fp = NULL; struct timespec ts; int i, n, nerrors, error; + mtx_lock(&Giant); + fdp = p->p_fd; if (((u_int)uap->fd) >= fdp->fd_nfiles || (fp = fdp->fd_ofiles[uap->fd]) == NULL || - (fp->f_type != DTYPE_KQUEUE)) - return (EBADF); - + (fp->f_type != DTYPE_KQUEUE)) { + error = EBADF; + goto done; + } fhold(fp); if (uap->timeout != NULL) { @@ -430,6 +443,7 @@ kevent(struct proc *p, struct kevent_args *uap) done: if (fp != NULL) fdrop(fp, p); + mtx_unlock(&Giant); return (error); } diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index c2e47d4..90a4f4c 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -98,6 +98,8 @@ struct execve_args { /* * execve() system call. + * + * MPSAFE */ int execve(p, uap) @@ -133,6 +135,8 @@ execve(p, uap) imgp->ps_strings = 0; imgp->auxarg_size = 0; + mtx_lock(&Giant); + /* * Allocate temporary demand zeroed space for argument and * environment strings @@ -445,17 +449,18 @@ exec_fail_dealloc: } if (error == 0) - return (0); + goto done2; exec_fail: if (imgp->vmspace_destroyed) { /* sorry, no more process anymore. exit gracefully */ exit1(p, W_EXITCODE(0, SIGABRT)); /* NOT REACHED */ - return(0); - } else { - return(error); - } + error = 0; + } +done2: + mtx_unlock(&Giant); + return(error); } int diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index de0640c..dea8ff0 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -105,6 +105,9 @@ init_fork_list(void *data __unused) } SYSINIT(fork_list, SI_SUB_INTRINSIC, SI_ORDER_ANY, init_fork_list, NULL); +/* + * MPSAFE + */ /* ARGSUSED */ int fork(p, uap) @@ -114,14 +117,19 @@ fork(p, uap) int error; struct proc *p2; + mtx_lock(&Giant); error = fork1(p, RFFDG | RFPROC, &p2); if (error == 0) { p->p_retval[0] = p2->p_pid; p->p_retval[1] = 0; } + mtx_unlock(&Giant); return error; } +/* + * MPSAFE + */ /* ARGSUSED */ int vfork(p, uap) @@ -131,14 +139,19 @@ vfork(p, uap) int error; struct proc *p2; + mtx_lock(&Giant); error = fork1(p, RFFDG | RFPROC | RFPPWAIT | RFMEM, &p2); if (error == 0) { p->p_retval[0] = p2->p_pid; p->p_retval[1] = 0; } + mtx_unlock(&Giant); return error; } +/* + * MPSAFE + */ int rfork(p, uap) struct proc *p; @@ -148,11 +161,13 @@ rfork(p, uap) struct proc *p2; /* mask kernel only flags out of the user flags */ + mtx_lock(&Giant); error = fork1(p, uap->flags & ~RFKERNELONLY, &p2); if (error == 0) { p->p_retval[0] = p2 ? p2->p_pid : 0; p->p_retval[1] = 0; } + mtx_unlock(&Giant); return error; } @@ -753,12 +768,8 @@ fork_return(p, frame) userret(p, frame, 0); #ifdef KTRACE if (KTRPOINT(p, KTR_SYSRET)) { - if (!mtx_owned(&Giant)) - mtx_lock(&Giant); ktrsysret(p->p_tracep, SYS_fork, 0, 0); } #endif - if (mtx_owned(&Giant)) - mtx_unlock(&Giant); mtx_assert(&Giant, MA_NOTOWNED); } diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index b80d2f1..abe5e0f 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -44,6 +44,9 @@ SYSCTL_INT(_jail, OID_AUTO, sysvipc_allowed, CTLFLAG_RW, &jail_sysvipc_allowed, 0, "Processes in jail can use System V IPC primitives"); +/* + * MPSAFE + */ int jail(p, uap) struct proc *p; @@ -56,15 +59,19 @@ jail(p, uap) struct jail j; struct chroot_args ca; + mtx_lock(&Giant); + /* Implicitly fail if already in jail. */ error = suser(p); if (error) - return (error); + goto done2; error = copyin(uap->jail, &j, sizeof j); if (error) - return (error); - if (j.version != 0) - return (EINVAL); + goto done2; + if (j.version != 0) { + error = EINVAL; + goto done2; + } MALLOC(pr, struct prison *, sizeof *pr , M_PRISON, M_WAITOK | M_ZERO); error = copyinstr(j.hostname, &pr->pr_host, sizeof pr->pr_host, 0); if (error) @@ -79,10 +86,13 @@ jail(p, uap) p->p_ucred = crcopy(p->p_ucred); p->p_ucred->cr_prison = pr; pr->pr_ref = 1; + mtx_unlock(&Giant); return (0); bail: FREE(pr, M_PRISON); +done2: + mtx_unlock(&Giant); return (error); } |