summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordillon <dillon@FreeBSD.org>2001-09-01 03:04:31 +0000
committerdillon <dillon@FreeBSD.org>2001-09-01 03:04:31 +0000
commitd1a6cbe1d59ffdd8715479fc5ceb20e567812005 (patch)
tree6e2be2d0ad774719f30ae9d248628c0f48614db6
parent5610a6ae63a163468769d8b1400a386115b53ddf (diff)
downloadFreeBSD-src-d1a6cbe1d59ffdd8715479fc5ceb20e567812005.zip
FreeBSD-src-d1a6cbe1d59ffdd8715479fc5ceb20e567812005.tar.gz
Pushdown Giant for acct(), kqueue(), kevent(), execve(), fork(),
vfork(), rfork(), jail().
-rw-r--r--sys/kern/kern_acct.c15
-rw-r--r--sys/kern/kern_event.c26
-rw-r--r--sys/kern/kern_exec.c15
-rw-r--r--sys/kern/kern_fork.c19
-rw-r--r--sys/kern/kern_jail.c18
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);
}
OpenPOWER on IntegriCloud