summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/kern_descrip.c240
-rw-r--r--sys/kern/kern_linker.c80
-rw-r--r--sys/kern/kern_module.c71
-rw-r--r--sys/kern/kern_prot.c351
-rw-r--r--sys/kern/kern_resource.c102
-rw-r--r--sys/kern/kern_shutdown.c37
6 files changed, 669 insertions, 212 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index d040690..a09c8c2 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -116,6 +116,9 @@ struct getdtablesize_args {
int dummy;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
getdtablesize(p, uap)
@@ -123,8 +126,10 @@ getdtablesize(p, uap)
struct getdtablesize_args *uap;
{
+ mtx_lock(&Giant);
p->p_retval[0] =
min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc);
+ mtx_unlock(&Giant);
return (0);
}
@@ -140,6 +145,9 @@ struct dup2_args {
u_int to;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
dup2(p, uap)
@@ -150,20 +158,23 @@ dup2(p, uap)
register u_int old = uap->from, new = uap->to;
int i, error;
+ mtx_lock(&Giant);
retry:
if (old >= fdp->fd_nfiles ||
fdp->fd_ofiles[old] == NULL ||
new >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur ||
new >= maxfilesperproc) {
- return (EBADF);
+ error = EBADF;
+ goto done2;
}
if (old == new) {
p->p_retval[0] = new;
- return (0);
+ error = 0;
+ goto done2;
}
if (new >= fdp->fd_nfiles) {
if ((error = fdalloc(p, new, &i)))
- return (error);
+ goto done2;
if (new != i)
panic("dup2: fdalloc");
/*
@@ -171,7 +182,10 @@ retry:
*/
goto retry;
}
- return (do_dup(fdp, (int)old, (int)new, p->p_retval, p));
+ error = do_dup(fdp, (int)old, (int)new, p->p_retval, p);
+done2:
+ mtx_unlock(&Giant);
+ return(error);
}
/*
@@ -182,6 +196,9 @@ struct dup_args {
u_int fd;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
dup(p, uap)
@@ -192,13 +209,19 @@ dup(p, uap)
u_int old;
int new, error;
+ mtx_lock(&Giant);
old = uap->fd;
fdp = p->p_fd;
- if (old >= fdp->fd_nfiles || fdp->fd_ofiles[old] == NULL)
- return (EBADF);
+ if (old >= fdp->fd_nfiles || fdp->fd_ofiles[old] == NULL) {
+ error = EBADF;
+ goto done2;
+ }
if ((error = fdalloc(p, 0, &new)))
- return (error);
- return (do_dup(fdp, (int)old, new, p->p_retval, p));
+ goto done2;
+ error = do_dup(fdp, (int)old, new, p->p_retval, p);
+done2:
+ mtx_unlock(&Giant);
+ return (error);
}
/*
@@ -211,46 +234,57 @@ struct fcntl_args {
long arg;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
fcntl(p, uap)
struct proc *p;
register struct fcntl_args *uap;
{
- register struct filedesc *fdp = p->p_fd;
+ register struct filedesc *fdp;
register struct file *fp;
register char *pop;
struct vnode *vp;
- int i, tmp, error, flg = F_POSIX;
+ int i, tmp, error = 0, flg = F_POSIX;
struct flock fl;
u_int newmin;
+ mtx_lock(&Giant);
+
+ fdp = p->p_fd;
if ((unsigned)uap->fd >= fdp->fd_nfiles ||
- (fp = fdp->fd_ofiles[uap->fd]) == NULL)
- return (EBADF);
+ (fp = fdp->fd_ofiles[uap->fd]) == NULL) {
+ error = EBADF;
+ goto done2;
+ }
pop = &fdp->fd_ofileflags[uap->fd];
switch (uap->cmd) {
case F_DUPFD:
newmin = uap->arg;
if (newmin >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur ||
- newmin >= maxfilesperproc)
- return (EINVAL);
+ newmin >= maxfilesperproc) {
+ error = EINVAL;
+ break;
+ }
if ((error = fdalloc(p, newmin, &i)))
- return (error);
- return (do_dup(fdp, uap->fd, i, p->p_retval, p));
+ break;
+ error = do_dup(fdp, uap->fd, i, p->p_retval, p);
+ break;
case F_GETFD:
p->p_retval[0] = *pop & 1;
- return (0);
+ break;
case F_SETFD:
*pop = (*pop &~ 1) | (uap->arg & 1);
- return (0);
+ break;
case F_GETFL:
p->p_retval[0] = OFLAGS(fp->f_flag);
- return (0);
+ break;
case F_SETFL:
fhold(fp);
@@ -260,39 +294,41 @@ fcntl(p, uap)
error = fo_ioctl(fp, FIONBIO, (caddr_t)&tmp, p);
if (error) {
fdrop(fp, p);
- return (error);
+ break;
}
tmp = fp->f_flag & FASYNC;
error = fo_ioctl(fp, FIOASYNC, (caddr_t)&tmp, p);
if (!error) {
fdrop(fp, p);
- return (0);
+ break;
}
fp->f_flag &= ~FNONBLOCK;
tmp = 0;
(void)fo_ioctl(fp, FIONBIO, (caddr_t)&tmp, p);
fdrop(fp, p);
- return (error);
+ break;
case F_GETOWN:
fhold(fp);
error = fo_ioctl(fp, FIOGETOWN, (caddr_t)p->p_retval, p);
fdrop(fp, p);
- return(error);
+ break;
case F_SETOWN:
fhold(fp);
error = fo_ioctl(fp, FIOSETOWN, (caddr_t)&uap->arg, p);
fdrop(fp, p);
- return(error);
+ break;
case F_SETLKW:
flg |= F_WAIT;
/* Fall into F_SETLK */
case F_SETLK:
- if (fp->f_type != DTYPE_VNODE)
- return (EBADF);
+ if (fp->f_type != DTYPE_VNODE) {
+ error = EBADF;
+ break;
+ }
vp = (struct vnode *)fp->f_data;
/*
@@ -304,14 +340,15 @@ fcntl(p, uap)
sizeof(fl));
if (error) {
fdrop(fp, p);
- return (error);
+ break;
}
if (fl.l_whence == SEEK_CUR) {
if (fp->f_offset < 0 ||
(fl.l_start > 0 &&
fp->f_offset > OFF_MAX - fl.l_start)) {
fdrop(fp, p);
- return (EOVERFLOW);
+ error = EOVERFLOW;
+ break;
}
fl.l_start += fp->f_offset;
}
@@ -344,11 +381,12 @@ fcntl(p, uap)
break;
}
fdrop(fp, p);
- return(error);
-
+ break;
case F_GETLK:
- if (fp->f_type != DTYPE_VNODE)
- return (EBADF);
+ if (fp->f_type != DTYPE_VNODE) {
+ error = EBADF;
+ break;
+ }
vp = (struct vnode *)fp->f_data;
/*
* copyin/lockop may block
@@ -359,12 +397,13 @@ fcntl(p, uap)
sizeof(fl));
if (error) {
fdrop(fp, p);
- return (error);
+ break;
}
if (fl.l_type != F_RDLCK && fl.l_type != F_WRLCK &&
fl.l_type != F_UNLCK) {
fdrop(fp, p);
- return (EINVAL);
+ error = EINVAL;
+ break;
}
if (fl.l_whence == SEEK_CUR) {
if ((fl.l_start > 0 &&
@@ -372,7 +411,8 @@ fcntl(p, uap)
(fl.l_start < 0 &&
fp->f_offset < OFF_MIN - fl.l_start)) {
fdrop(fp, p);
- return (EOVERFLOW);
+ error = EOVERFLOW;
+ break;
}
fl.l_start += fp->f_offset;
}
@@ -383,11 +423,14 @@ fcntl(p, uap)
error = copyout((caddr_t)&fl,
(caddr_t)(intptr_t)uap->arg, sizeof(fl));
}
- return(error);
+ break;
default:
- return (EINVAL);
+ error = EINVAL;
+ break;
}
- /* NOTREACHED */
+done2:
+ mtx_unlock(&Giant);
+ return (error);
}
/*
@@ -568,19 +611,27 @@ struct close_args {
int fd;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
close(p, uap)
struct proc *p;
struct close_args *uap;
{
- register struct filedesc *fdp = p->p_fd;
+ register struct filedesc *fdp;
register struct file *fp;
register int fd = uap->fd;
+ int error = 0;
+ mtx_lock(&Giant);
+ fdp = p->p_fd;
if ((unsigned)fd >= fdp->fd_nfiles ||
- (fp = fdp->fd_ofiles[fd]) == NULL)
- return (EBADF);
+ (fp = fdp->fd_ofiles[fd]) == NULL) {
+ error = EBADF;
+ goto done2;
+ }
#if 0
if (fdp->fd_ofileflags[fd] & UF_MAPPED)
(void) munmapfd(p, fd);
@@ -598,7 +649,10 @@ close(p, uap)
fdp->fd_freefile = fd;
if (fd < fdp->fd_knlistsize)
knote_fdclose(p, fd);
- return (closef(fp, p));
+ error = closef(fp, p);
+done2:
+ mtx_unlock(&Giant);
+ return(error);
}
#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
@@ -611,6 +665,9 @@ struct ofstat_args {
struct ostat *sb;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
ofstat(p, uap)
@@ -623,9 +680,13 @@ ofstat(p, uap)
struct ostat oub;
int error;
+ mtx_lock(&Giant);
+
if ((unsigned)uap->fd >= fdp->fd_nfiles ||
- (fp = fdp->fd_ofiles[uap->fd]) == NULL)
- return (EBADF);
+ (fp = fdp->fd_ofiles[uap->fd]) == NULL) {
+ error = EBADF;
+ goto done2;
+ }
fhold(fp);
error = fo_stat(fp, &ub, p);
if (error == 0) {
@@ -633,6 +694,8 @@ ofstat(p, uap)
error = copyout((caddr_t)&oub, (caddr_t)uap->sb, sizeof (oub));
}
fdrop(fp, p);
+done2:
+ mtx_unlock(&Giant);
return (error);
}
#endif /* COMPAT_43 || COMPAT_SUNOS */
@@ -646,25 +709,35 @@ struct fstat_args {
struct stat *sb;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
fstat(p, uap)
struct proc *p;
register struct fstat_args *uap;
{
- register struct filedesc *fdp = p->p_fd;
+ register struct filedesc *fdp;
register struct file *fp;
struct stat ub;
int error;
+ mtx_lock(&Giant);
+ fdp = p->p_fd;
+
if ((unsigned)uap->fd >= fdp->fd_nfiles ||
- (fp = fdp->fd_ofiles[uap->fd]) == NULL)
- return (EBADF);
+ (fp = fdp->fd_ofiles[uap->fd]) == NULL) {
+ error = EBADF;
+ goto done2;
+ }
fhold(fp);
error = fo_stat(fp, &ub, p);
if (error == 0)
error = copyout((caddr_t)&ub, (caddr_t)uap->sb, sizeof (ub));
fdrop(fp, p);
+done2:
+ mtx_unlock(&Giant);
return (error);
}
@@ -677,21 +750,29 @@ struct nfstat_args {
struct nstat *sb;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
nfstat(p, uap)
struct proc *p;
register struct nfstat_args *uap;
{
- register struct filedesc *fdp = p->p_fd;
+ register struct filedesc *fdp;
register struct file *fp;
struct stat ub;
struct nstat nub;
int error;
+ mtx_lock(&Giant);
+
+ fdp = p->p_fd;
if ((unsigned)uap->fd >= fdp->fd_nfiles ||
- (fp = fdp->fd_ofiles[uap->fd]) == NULL)
- return (EBADF);
+ (fp = fdp->fd_ofiles[uap->fd]) == NULL) {
+ error = EBADF;
+ goto done2;
+ }
fhold(fp);
error = fo_stat(fp, &ub, p);
if (error == 0) {
@@ -699,6 +780,8 @@ nfstat(p, uap)
error = copyout((caddr_t)&nub, (caddr_t)uap->sb, sizeof (nub));
}
fdrop(fp, p);
+done2:
+ mtx_unlock(&Giant);
return (error);
}
@@ -711,28 +794,38 @@ struct fpathconf_args {
int name;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
fpathconf(p, uap)
struct proc *p;
register struct fpathconf_args *uap;
{
- struct filedesc *fdp = p->p_fd;
+ struct filedesc *fdp;
struct file *fp;
struct vnode *vp;
int error = 0;
+ mtx_lock(&Giant);
+ fdp = p->p_fd;
+
if ((unsigned)uap->fd >= fdp->fd_nfiles ||
- (fp = fdp->fd_ofiles[uap->fd]) == NULL)
- return (EBADF);
+ (fp = fdp->fd_ofiles[uap->fd]) == NULL) {
+ error = EBADF;
+ goto done2;
+ }
fhold(fp);
switch (fp->f_type) {
case DTYPE_PIPE:
case DTYPE_SOCKET:
- if (uap->name != _PC_PIPE_BUF)
- return (EINVAL);
+ if (uap->name != _PC_PIPE_BUF) {
+ error = EINVAL;
+ goto done2;
+ }
p->p_retval[0] = PIPE_BUF;
error = 0;
break;
@@ -746,6 +839,8 @@ fpathconf(p, uap)
break;
}
fdrop(fp, p);
+done2:
+ mtx_unlock(&Giant);
return(error);
}
@@ -1274,6 +1369,9 @@ struct flock_args {
int how;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
flock(p, uap)
@@ -1284,12 +1382,19 @@ flock(p, uap)
register struct file *fp;
struct vnode *vp;
struct flock lf;
+ int error;
+
+ mtx_lock(&Giant);
if ((unsigned)uap->fd >= fdp->fd_nfiles ||
- (fp = fdp->fd_ofiles[uap->fd]) == NULL)
- return (EBADF);
- if (fp->f_type != DTYPE_VNODE)
- return (EOPNOTSUPP);
+ (fp = fdp->fd_ofiles[uap->fd]) == NULL) {
+ error = EBADF;
+ goto done2;
+ }
+ if (fp->f_type != DTYPE_VNODE) {
+ error = EOPNOTSUPP;
+ goto done2;
+ }
vp = (struct vnode *)fp->f_data;
lf.l_whence = SEEK_SET;
lf.l_start = 0;
@@ -1297,18 +1402,25 @@ flock(p, uap)
if (uap->how & LOCK_UN) {
lf.l_type = F_UNLCK;
fp->f_flag &= ~FHASLOCK;
- return (VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK));
+ error = VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK);
+ goto done2;
}
if (uap->how & LOCK_EX)
lf.l_type = F_WRLCK;
else if (uap->how & LOCK_SH)
lf.l_type = F_RDLCK;
- else
- return (EBADF);
+ else {
+ error = EBADF;
+ goto done2;
+ }
fp->f_flag |= FHASLOCK;
if (uap->how & LOCK_NB)
- return (VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK));
- return (VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK|F_WAIT));
+ error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK);
+ else
+ error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK|F_WAIT);
+done2:
+ mtx_unlock(&Giant);
+ return (error);
}
/*
diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c
index 48f414b..7b5753b 100644
--- a/sys/kern/kern_linker.c
+++ b/sys/kern/kern_linker.c
@@ -36,6 +36,7 @@
#include <sys/sysent.h>
#include <sys/proc.h>
#include <sys/lock.h>
+#include <sys/mutex.h>
#include <sys/module.h>
#include <sys/linker.h>
#include <sys/fcntl.h>
@@ -692,11 +693,14 @@ linker_ddb_symbol_values(c_linker_sym_t sym, linker_symval_t *symval)
/*
* Syscalls.
*/
-
+/*
+ * MPSAFE
+ */
int
kldload(struct proc* p, struct kldload_args* uap)
{
- char* pathname, *realpath;
+ char *pathname = NULL;
+ char *realpath = NULL;
const char *filename;
linker_file_t lf;
int error = 0;
@@ -706,10 +710,11 @@ kldload(struct proc* p, struct kldload_args* uap)
if (securelevel > 0) /* redundant, but that's OK */
return EPERM;
+ mtx_lock(&Giant);
+
if ((error = suser(p)) != 0)
- return error;
+ goto out;
- realpath = NULL;
pathname = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
if ((error = copyinstr(SCARG(uap, file), pathname, MAXPATHLEN, NULL)) != 0)
goto out;
@@ -737,9 +742,13 @@ out:
free(pathname, M_TEMP);
if (realpath)
free(realpath, M_LINKER);
- return error;
+ mtx_unlock(&Giant);
+ return (error);
}
+/*
+ * MPSAFE
+ */
int
kldunload(struct proc* p, struct kldunload_args* uap)
{
@@ -749,8 +758,10 @@ kldunload(struct proc* p, struct kldunload_args* uap)
if (securelevel > 0) /* redundant, but that's OK */
return EPERM;
+ mtx_lock(&Giant);
+
if ((error = suser(p)) != 0)
- return error;
+ goto out;
lf = linker_find_file_by_id(SCARG(uap, fileid));
if (lf) {
@@ -764,13 +775,17 @@ kldunload(struct proc* p, struct kldunload_args* uap)
error = linker_file_unload(lf);
if (error)
lf->userrefs++;
- } else
+ } else {
error = ENOENT;
-
+ }
out:
- return error;
+ mtx_unlock(&Giant);
+ return (error);
}
+/*
+ * MPSAFE
+ */
int
kldfind(struct proc* p, struct kldfind_args* uap)
{
@@ -779,6 +794,8 @@ kldfind(struct proc* p, struct kldfind_args* uap)
linker_file_t lf;
int error = 0;
+ mtx_lock(&Giant);
+
p->p_retval[0] = -1;
pathname = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
@@ -796,21 +813,27 @@ kldfind(struct proc* p, struct kldfind_args* uap)
out:
if (pathname)
free(pathname, M_TEMP);
- return error;
+ mtx_unlock(&Giant);
+ return (error);
}
+/*
+ * MPSAFE
+ */
int
kldnext(struct proc* p, struct kldnext_args* uap)
{
linker_file_t lf;
int error = 0;
+ mtx_lock(&Giant);
+
if (SCARG(uap, fileid) == 0) {
if (TAILQ_FIRST(&linker_files))
p->p_retval[0] = TAILQ_FIRST(&linker_files)->id;
else
p->p_retval[0] = 0;
- return 0;
+ goto out;
}
lf = linker_find_file_by_id(SCARG(uap, fileid));
@@ -819,12 +842,17 @@ kldnext(struct proc* p, struct kldnext_args* uap)
p->p_retval[0] = TAILQ_NEXT(lf, link)->id;
else
p->p_retval[0] = 0;
- } else
+ } else {
error = ENOENT;
-
- return error;
+ }
+out:
+ mtx_unlock(&Giant);
+ return (error);
}
+/*
+ * MPSAFE
+ */
int
kldstat(struct proc* p, struct kldstat_args* uap)
{
@@ -834,6 +862,8 @@ kldstat(struct proc* p, struct kldstat_args* uap)
struct kld_file_stat* stat;
int namelen;
+ mtx_lock(&Giant);
+
lf = linker_find_file_by_id(SCARG(uap, fileid));
if (!lf) {
error = ENOENT;
@@ -869,27 +899,36 @@ kldstat(struct proc* p, struct kldstat_args* uap)
p->p_retval[0] = 0;
out:
- return error;
+ mtx_unlock(&Giant);
+ return (error);
}
+/*
+ * MPSAFE
+ */
int
kldfirstmod(struct proc* p, struct kldfirstmod_args* uap)
{
linker_file_t lf;
int error = 0;
+ mtx_lock(&Giant);
lf = linker_find_file_by_id(SCARG(uap, fileid));
if (lf) {
if (TAILQ_FIRST(&lf->modules))
p->p_retval[0] = module_getid(TAILQ_FIRST(&lf->modules));
else
p->p_retval[0] = 0;
- } else
+ } else {
error = ENOENT;
-
- return error;
+ }
+ mtx_unlock(&Giant);
+ return (error);
}
+/*
+ * MPSAFE
+ */
int
kldsym(struct proc *p, struct kldsym_args *uap)
{
@@ -900,6 +939,8 @@ kldsym(struct proc *p, struct kldsym_args *uap)
struct kld_sym_lookup lookup;
int error = 0;
+ mtx_lock(&Giant);
+
if ((error = copyin(SCARG(uap, data), &lookup, sizeof(lookup))) != 0)
goto out;
if (lookup.version != sizeof(lookup) || SCARG(uap, cmd) != KLDSYM_LOOKUP) {
@@ -940,7 +981,8 @@ kldsym(struct proc *p, struct kldsym_args *uap)
out:
if (symstr)
free(symstr, M_TEMP);
- return error;
+ mtx_unlock(&Giant);
+ return (error);
}
/*
diff --git a/sys/kern/kern_module.c b/sys/kern/kern_module.c
index b9d35d7..3fbdb72 100644
--- a/sys/kern/kern_module.c
+++ b/sys/kern/kern_module.c
@@ -36,6 +36,8 @@
#include <sys/module.h>
#include <sys/linker.h>
#include <sys/proc.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
static MALLOC_DEFINE(M_MODULE, "module", "module data structures");
@@ -216,48 +218,67 @@ module_setspecific(module_t mod, modspecific_t *datap)
/*
* Syscalls.
*/
+/*
+ * MPSAFE
+ */
int
modnext(struct proc* p, struct modnext_args* uap)
{
module_t mod;
+ int error = 0;
+
+ mtx_lock(&Giant);
p->p_retval[0] = -1;
if (SCARG(uap, modid) == 0) {
mod = TAILQ_FIRST(&modules);
- if (mod) {
+ if (mod)
p->p_retval[0] = mod->id;
- return 0;
- } else
- return ENOENT;
+ else
+ error = ENOENT;
+ goto done2;
}
mod = module_lookupbyid(SCARG(uap, modid));
- if (!mod)
- return ENOENT;
+ if (mod == NULL) {
+ error = ENOENT;
+ goto done2;
+ }
if (TAILQ_NEXT(mod, link))
p->p_retval[0] = TAILQ_NEXT(mod, link)->id;
else
p->p_retval[0] = 0;
- return 0;
+done2:
+ mtx_unlock(&Giant);
+ return (error);
}
+/*
+ * MPSAFE
+ */
int
modfnext(struct proc* p, struct modfnext_args* uap)
{
module_t mod;
+ int error;
p->p_retval[0] = -1;
- mod = module_lookupbyid(SCARG(uap, modid));
- if (!mod)
- return ENOENT;
+ mtx_lock(&Giant);
- if (TAILQ_NEXT(mod, flink))
- p->p_retval[0] = TAILQ_NEXT(mod, flink)->id;
- else
- p->p_retval[0] = 0;
- return 0;
+ mod = module_lookupbyid(SCARG(uap, modid));
+ if (mod == NULL) {
+ error = ENOENT;
+ } else {
+ error = 0;
+ if (TAILQ_NEXT(mod, flink))
+ p->p_retval[0] = TAILQ_NEXT(mod, flink)->id;
+ else
+ p->p_retval[0] = 0;
+ }
+ mtx_unlock(&Giant);
+ return (error);
}
struct module_stat_v1 {
@@ -267,6 +288,9 @@ struct module_stat_v1 {
int id;
};
+/*
+ * MPSAFE
+ */
int
modstat(struct proc* p, struct modstat_args* uap)
{
@@ -276,9 +300,13 @@ modstat(struct proc* p, struct modstat_args* uap)
int version;
struct module_stat* stat;
+ mtx_lock(&Giant);
+
mod = module_lookupbyid(SCARG(uap, modid));
- if (!mod)
- return ENOENT;
+ if (mod == NULL) {
+ error = ENOENT;
+ goto out;
+ }
stat = SCARG(uap, stat);
@@ -315,9 +343,13 @@ modstat(struct proc* p, struct modstat_args* uap)
p->p_retval[0] = 0;
out:
+ mtx_unlock(&Giant);
return error;
}
+/*
+ * MPSAFE
+ */
int
modfind(struct proc* p, struct modfind_args* uap)
{
@@ -328,12 +360,13 @@ modfind(struct proc* p, struct modfind_args* uap)
if ((error = copyinstr(SCARG(uap, name), name, sizeof name, 0)) != 0)
goto out;
+ mtx_lock(&Giant);
mod = module_lookupbyname(name);
- if (!mod)
+ if (mod == NULL)
error = ENOENT;
else
p->p_retval[0] = mod->id;
-
+ mtx_unlock(&Giant);
out:
return error;
}
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index 2802b01..baa73dd 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -73,9 +73,12 @@ struct getpid_args {
#endif
/*
- * getpid - MP SAFE
+ * getpid
*/
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
getpid(p, uap)
@@ -83,17 +86,19 @@ getpid(p, uap)
struct getpid_args *uap;
{
+ mtx_lock(&Giant);
p->p_retval[0] = p->p_pid;
#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
PROC_LOCK(p);
p->p_retval[1] = p->p_pptr->p_pid;
PROC_UNLOCK(p);
#endif
+ mtx_unlock(&Giant);
return (0);
}
/*
- * getppid - MP SAFE
+ * getppid
*/
#ifndef _SYS_SYSPROTO_H_
@@ -101,6 +106,9 @@ struct getppid_args {
int dummy;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
getppid(p, uap)
@@ -108,9 +116,11 @@ getppid(p, uap)
struct getppid_args *uap;
{
+ mtx_lock(&Giant);
PROC_LOCK(p);
p->p_retval[0] = p->p_pptr->p_pid;
PROC_UNLOCK(p);
+ mtx_unlock(&Giant);
return (0);
}
@@ -124,14 +134,18 @@ struct getpgrp_args {
int dummy;
};
#endif
-
+/*
+ * MPSAFE
+ */
int
getpgrp(p, uap)
struct proc *p;
struct getpgrp_args *uap;
{
+ mtx_lock(&Giant);
p->p_retval[0] = p->p_pgrp->pg_id;
+ mtx_unlock(&Giant);
return (0);
}
@@ -142,27 +156,35 @@ struct getpgid_args {
};
#endif
+/*
+ * MPSAFE
+ */
int
getpgid(p, uap)
struct proc *p;
struct getpgid_args *uap;
{
struct proc *pt;
- int error;
+ int error = 0;
+ mtx_lock(&Giant);
if (uap->pid == 0)
p->p_retval[0] = p->p_pgrp->pg_id;
else {
- if ((pt = pfind(uap->pid)) == NULL)
- return ESRCH;
+ if ((pt = pfind(uap->pid)) == NULL) {
+ error = ESRCH;
+ goto done2;
+ }
if ((error = p_cansee(p, pt))) {
PROC_UNLOCK(pt);
- return (error);
+ goto done2;
}
p->p_retval[0] = pt->p_pgrp->pg_id;
PROC_UNLOCK(pt);
}
- return 0;
+done2:
+ mtx_unlock(&Giant);
+ return (error);
}
/*
@@ -174,27 +196,35 @@ struct getsid_args {
};
#endif
+/*
+ * MPSAFE
+ */
int
getsid(p, uap)
struct proc *p;
struct getsid_args *uap;
{
struct proc *pt;
- int error;
+ int error = 0;
- if (uap->pid == 0)
+ mtx_lock(&Giant);
+ if (uap->pid == 0) {
p->p_retval[0] = p->p_session->s_sid;
- else {
- if ((pt = pfind(uap->pid)) == NULL)
- return ESRCH;
+ } else {
+ if ((pt = pfind(uap->pid)) == NULL) {
+ error = ESRCH;
+ goto done2;
+ }
if ((error = p_cansee(p, pt))) {
PROC_UNLOCK(pt);
- return (error);
+ goto done2;
}
p->p_retval[0] = pt->p_session->s_sid;
PROC_UNLOCK(pt);
}
- return 0;
+done2:
+ mtx_unlock(&Giant);
+ return (error);
}
@@ -207,6 +237,9 @@ struct getuid_args {
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
getuid(p, uap)
@@ -214,10 +247,12 @@ getuid(p, uap)
struct getuid_args *uap;
{
+ mtx_lock(&Giant);
p->p_retval[0] = p->p_ucred->cr_ruid;
#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
p->p_retval[1] = p->p_ucred->cr_uid;
#endif
+ mtx_unlock(&Giant);
return (0);
}
@@ -237,7 +272,9 @@ geteuid(p, uap)
struct geteuid_args *uap;
{
+ mtx_lock(&Giant);
p->p_retval[0] = p->p_ucred->cr_uid;
+ mtx_unlock(&Giant);
return (0);
}
@@ -250,6 +287,9 @@ struct getgid_args {
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
getgid(p, uap)
@@ -257,10 +297,12 @@ getgid(p, uap)
struct getgid_args *uap;
{
+ mtx_lock(&Giant);
p->p_retval[0] = p->p_ucred->cr_rgid;
#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
p->p_retval[1] = p->p_ucred->cr_groups[0];
#endif
+ mtx_unlock(&Giant);
return (0);
}
@@ -275,6 +317,9 @@ struct getegid_args {
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
getegid(p, uap)
@@ -282,7 +327,9 @@ getegid(p, uap)
struct getegid_args *uap;
{
+ mtx_lock(&Giant);
p->p_retval[0] = p->p_ucred->cr_groups[0];
+ mtx_unlock(&Giant);
return (0);
}
@@ -292,27 +339,38 @@ struct getgroups_args {
gid_t *gidset;
};
#endif
+/*
+ * MPSAFE
+ */
int
getgroups(p, uap)
struct proc *p;
register struct getgroups_args *uap;
{
- struct ucred *cred = p->p_ucred;
+ struct ucred *cred;
u_int ngrp;
- int error;
+ int error = 0;
+ mtx_lock(&Giant);
+ cred = p->p_ucred;
if ((ngrp = uap->gidsetsize) == 0) {
p->p_retval[0] = cred->cr_ngroups;
- return (0);
+ error = 0;
+ goto done2;
+ }
+ if (ngrp < cred->cr_ngroups) {
+ error = EINVAL;
+ goto done2;
}
- if (ngrp < cred->cr_ngroups)
- return (EINVAL);
ngrp = cred->cr_ngroups;
if ((error = copyout((caddr_t)cred->cr_groups,
- (caddr_t)uap->gidset, ngrp * sizeof(gid_t))))
- return (error);
+ (caddr_t)uap->gidset, ngrp * sizeof(gid_t)))) {
+ goto done2;
+ }
p->p_retval[0] = ngrp;
- return (0);
+done2:
+ mtx_unlock(&Giant);
+ return (error);
}
#ifndef _SYS_SYSPROTO_H_
@@ -321,20 +379,27 @@ struct setsid_args {
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
setsid(p, uap)
register struct proc *p;
struct setsid_args *uap;
{
+ int error;
+ mtx_lock(&Giant);
if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) {
- return (EPERM);
+ error = EPERM;
} else {
(void)enterpgrp(p, p->p_pid, 1);
p->p_retval[0] = p->p_pid;
- return (0);
+ error = 0;
}
+ mtx_unlock(&Giant);
+ return (error);
}
/*
@@ -356,6 +421,9 @@ struct setpgid_args {
int pgid; /* target pgrp id */
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
setpgid(curp, uap)
@@ -368,24 +436,30 @@ setpgid(curp, uap)
if (uap->pgid < 0)
return (EINVAL);
+
+ mtx_lock(&Giant);
+
if (uap->pid != 0 && uap->pid != curp->p_pid) {
if ((targp = pfind(uap->pid)) == NULL || !inferior(targp)) {
if (targp)
PROC_UNLOCK(targp);
- return (ESRCH);
+ error = ESRCH;
+ goto done2;
}
if ((error = p_cansee(curproc, targp))) {
PROC_UNLOCK(targp);
- return (error);
+ goto done2;
}
if (targp->p_pgrp == NULL ||
targp->p_session != curp->p_session) {
PROC_UNLOCK(targp);
- return (EPERM);
+ error = EPERM;
+ goto done2;
}
if (targp->p_flag & P_EXEC) {
PROC_UNLOCK(targp);
- return (EACCES);
+ error = EACCES;
+ goto done2;
}
} else {
targp = curp;
@@ -393,19 +467,25 @@ setpgid(curp, uap)
}
if (SESS_LEADER(targp)) {
PROC_UNLOCK(targp);
- return (EPERM);
+ error = EPERM;
+ goto done2;
}
- if (uap->pgid == 0)
+ if (uap->pgid == 0) {
uap->pgid = targp->p_pid;
- else if (uap->pgid != targp->p_pid)
+ } else if (uap->pgid != targp->p_pid) {
if ((pgrp = pgfind(uap->pgid)) == 0 ||
pgrp->pg_session != curp->p_session) {
PROC_UNLOCK(targp);
- return (EPERM);
+ error = EPERM;
+ goto done2;
}
+ }
/* XXX: We should probably hold the lock across enterpgrp. */
PROC_UNLOCK(targp);
- return (enterpgrp(targp, uap->pgid, 0));
+ error = enterpgrp(targp, uap->pgid, 0);
+done2:
+ mtx_unlock(&Giant);
+ return (error);
}
/*
@@ -425,6 +505,9 @@ struct setuid_args {
uid_t uid;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
setuid(p, uap)
@@ -433,10 +516,12 @@ setuid(p, uap)
{
struct ucred *newcred, *oldcred;
uid_t uid;
- int error;
+ int error = 0;
uid = uap->uid;
oldcred = p->p_ucred;
+ mtx_lock(&Giant);
+
/*
* See if we have "permission" by POSIX 1003.1 rules.
*
@@ -462,7 +547,7 @@ setuid(p, uap)
uid != oldcred->cr_uid && /* allow setuid(geteuid()) */
#endif
(error = suser_xxx(oldcred, NULL, PRISON_ROOT)))
- return (error);
+ goto done2;
newcred = crdup(oldcred);
#ifdef _POSIX_SAVED_IDS
@@ -507,7 +592,9 @@ setuid(p, uap)
}
p->p_ucred = newcred;
crfree(oldcred);
- return (0);
+done2:
+ mtx_unlock(&Giant);
+ return (error);
}
#ifndef _SYS_SYSPROTO_H_
@@ -515,6 +602,9 @@ struct seteuid_args {
uid_t euid;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
seteuid(p, uap)
@@ -523,14 +613,17 @@ seteuid(p, uap)
{
struct ucred *newcred, *oldcred;
uid_t euid;
- int error;
+ int error = 0;
euid = uap->euid;
+
+ mtx_lock(&Giant);
oldcred = p->p_ucred;
if (euid != oldcred->cr_ruid && /* allow seteuid(getuid()) */
euid != oldcred->cr_svuid && /* allow seteuid(saved uid) */
- (error = suser_xxx(oldcred, NULL, PRISON_ROOT)))
- return (error);
+ (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) {
+ goto done2;
+ }
/*
* Everything's okay, do it. Copy credentials so other references do
* not see our changes.
@@ -542,7 +635,9 @@ seteuid(p, uap)
}
p->p_ucred = newcred;
crfree(oldcred);
- return (0);
+done2:
+ mtx_unlock(&Giant);
+ return (error);
}
#ifndef _SYS_SYSPROTO_H_
@@ -550,6 +645,9 @@ struct setgid_args {
gid_t gid;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
setgid(p, uap)
@@ -558,9 +656,11 @@ setgid(p, uap)
{
struct ucred *newcred, *oldcred;
gid_t gid;
- int error;
+ int error = 0;
gid = uap->gid;
+
+ mtx_lock(&Giant);
oldcred = p->p_ucred;
/*
* See if we have "permission" by POSIX 1003.1 rules.
@@ -580,8 +680,9 @@ setgid(p, uap)
#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */
gid != oldcred->cr_groups[0] && /* allow setgid(getegid()) */
#endif
- (error = suser_xxx(oldcred, NULL, PRISON_ROOT)))
- return (error);
+ (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) {
+ goto done2;
+ }
newcred = crdup(oldcred);
#ifdef _POSIX_SAVED_IDS
@@ -625,7 +726,9 @@ setgid(p, uap)
}
p->p_ucred = newcred;
crfree(oldcred);
- return (0);
+done2:
+ mtx_unlock(&Giant);
+ return (error);
}
#ifndef _SYS_SYSPROTO_H_
@@ -633,6 +736,9 @@ struct setegid_args {
gid_t egid;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
setegid(p, uap)
@@ -641,14 +747,17 @@ setegid(p, uap)
{
struct ucred *newcred, *oldcred;
gid_t egid;
- int error;
+ int error = 0;
egid = uap->egid;
+
+ mtx_lock(&Giant);
oldcred = p->p_ucred;
if (egid != oldcred->cr_rgid && /* allow setegid(getgid()) */
egid != oldcred->cr_svgid && /* allow setegid(saved gid) */
- (error = suser_xxx(oldcred, NULL, PRISON_ROOT)))
- return (error);
+ (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) {
+ goto done2;
+ }
newcred = crdup(oldcred);
if (oldcred->cr_groups[0] != egid) {
change_egid(newcred, egid);
@@ -656,7 +765,9 @@ setegid(p, uap)
}
p->p_ucred = newcred;
crfree(oldcred);
- return (0);
+done2:
+ mtx_unlock(&Giant);
+ return (error);
}
#ifndef _SYS_SYSPROTO_H_
@@ -665,6 +776,9 @@ struct setgroups_args {
gid_t *gidset;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
setgroups(p, uap)
@@ -675,12 +789,16 @@ setgroups(p, uap)
u_int ngrp;
int error;
+ mtx_lock(&Giant);
+
ngrp = uap->gidsetsize;
oldcred = p->p_ucred;
if ((error = suser_xxx(oldcred, NULL, PRISON_ROOT)))
- return (error);
- if (ngrp > NGROUPS)
- return (EINVAL);
+ goto done2;
+ if (ngrp > NGROUPS) {
+ error = EINVAL;
+ goto done2;
+ }
/*
* XXX A little bit lazy here. We could test if anything has
* changed before crcopy() and setting P_SUGID.
@@ -698,14 +816,16 @@ setgroups(p, uap)
if ((error = copyin((caddr_t)uap->gidset,
(caddr_t)newcred->cr_groups, ngrp * sizeof(gid_t)))) {
crfree(newcred);
- return (error);
+ goto done2;
}
newcred->cr_ngroups = ngrp;
}
setsugid(p);
p->p_ucred = newcred;
crfree(oldcred);
- return (0);
+done2:
+ mtx_unlock(&Giant);
+ return (error);
}
#ifndef _SYS_SYSPROTO_H_
@@ -714,6 +834,9 @@ struct setreuid_args {
uid_t euid;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
setreuid(p, uap)
@@ -722,17 +845,21 @@ setreuid(p, uap)
{
struct ucred *newcred, *oldcred;
uid_t ruid, euid;
- int error;
+ int error = 0;
ruid = uap->ruid;
euid = uap->euid;
+
+ mtx_lock(&Giant);
+
oldcred = p->p_ucred;
if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid &&
ruid != oldcred->cr_svuid) ||
(euid != (uid_t)-1 && euid != oldcred->cr_uid &&
euid != oldcred->cr_ruid && euid != oldcred->cr_svuid)) &&
- (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0)
- return (error);
+ (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) {
+ goto done2;
+ }
newcred = crdup(oldcred);
if (euid != (uid_t)-1 && oldcred->cr_uid != euid) {
change_euid(newcred, euid);
@@ -749,7 +876,9 @@ setreuid(p, uap)
}
p->p_ucred = newcred;
crfree(oldcred);
- return (0);
+done2:
+ mtx_unlock(&Giant);
+ return (error);
}
#ifndef _SYS_SYSPROTO_H_
@@ -758,6 +887,9 @@ struct setregid_args {
gid_t egid;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
setregid(p, uap)
@@ -766,17 +898,21 @@ setregid(p, uap)
{
struct ucred *newcred, *oldcred;
gid_t rgid, egid;
- int error;
+ int error = 0;
rgid = uap->rgid;
egid = uap->egid;
+
+ mtx_lock(&Giant);
+
oldcred = p->p_ucred;
if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid &&
rgid != oldcred->cr_svgid) ||
(egid != (gid_t)-1 && egid != oldcred->cr_groups[0] &&
egid != oldcred->cr_rgid && egid != oldcred->cr_svgid)) &&
- (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0)
- return (error);
+ (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) {
+ goto done2;
+ }
newcred = crdup(oldcred);
if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) {
@@ -794,7 +930,9 @@ setregid(p, uap)
}
p->p_ucred = newcred;
crfree(oldcred);
- return (0);
+done2:
+ mtx_unlock(&Giant);
+ return (error);
}
/*
@@ -809,6 +947,9 @@ struct setresuid_args {
uid_t suid;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
setresuid(p, uap)
@@ -822,6 +963,8 @@ setresuid(p, uap)
ruid = uap->ruid;
euid = uap->euid;
suid = uap->suid;
+
+ mtx_lock(&Giant);
oldcred = p->p_ucred;
if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid &&
ruid != oldcred->cr_svuid &&
@@ -832,8 +975,9 @@ setresuid(p, uap)
(suid != (uid_t)-1 && suid != oldcred->cr_ruid &&
suid != oldcred->cr_svuid &&
suid != oldcred->cr_uid)) &&
- (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0)
- return (error);
+ (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) {
+ goto done2;
+ }
newcred = crdup(oldcred);
if (euid != (uid_t)-1 && oldcred->cr_uid != euid) {
@@ -850,7 +994,10 @@ setresuid(p, uap)
}
p->p_ucred = newcred;
crfree(oldcred);
- return (0);
+ error = 0;
+done2:
+ mtx_unlock(&Giant);
+ return (error);
}
/*
@@ -865,6 +1012,9 @@ struct setresgid_args {
gid_t sgid;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
setresgid(p, uap)
@@ -878,6 +1028,8 @@ setresgid(p, uap)
rgid = uap->rgid;
egid = uap->egid;
sgid = uap->sgid;
+
+ mtx_lock(&Giant);
oldcred = p->p_ucred;
if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid &&
rgid != oldcred->cr_svgid &&
@@ -888,9 +1040,9 @@ setresgid(p, uap)
(sgid != (gid_t)-1 && sgid != oldcred->cr_rgid &&
sgid != oldcred->cr_svgid &&
sgid != oldcred->cr_groups[0])) &&
- (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0)
- return (error);
-
+ (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) {
+ goto done2;
+ }
newcred = crdup(oldcred);
if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) {
change_egid(newcred, egid);
@@ -906,7 +1058,10 @@ setresgid(p, uap)
}
p->p_ucred = newcred;
crfree(oldcred);
- return (0);
+ error = 0;
+done2:
+ mtx_unlock(&Giant);
+ return (error);
}
#ifndef _SYS_SYSPROTO_H_
@@ -916,15 +1071,21 @@ struct getresuid_args {
uid_t *suid;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
getresuid(p, uap)
register struct proc *p;
struct getresuid_args *uap;
{
- struct ucred *cred = p->p_ucred;
+ struct ucred *cred;
int error1 = 0, error2 = 0, error3 = 0;
+ mtx_lock(&Giant);
+ cred = p->p_ucred;
+
if (uap->ruid)
error1 = copyout((caddr_t)&cred->cr_ruid,
(caddr_t)uap->ruid, sizeof(cred->cr_ruid));
@@ -934,6 +1095,7 @@ getresuid(p, uap)
if (uap->suid)
error3 = copyout((caddr_t)&cred->cr_svuid,
(caddr_t)uap->suid, sizeof(cred->cr_svuid));
+ mtx_unlock(&Giant);
return error1 ? error1 : (error2 ? error2 : error3);
}
@@ -944,15 +1106,21 @@ struct getresgid_args {
gid_t *sgid;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
getresgid(p, uap)
register struct proc *p;
struct getresgid_args *uap;
{
- struct ucred *cred = p->p_ucred;
+ struct ucred *cred;
int error1 = 0, error2 = 0, error3 = 0;
+ mtx_lock(&Giant);
+ cred = p->p_ucred;
+
if (uap->rgid)
error1 = copyout((caddr_t)&cred->cr_rgid,
(caddr_t)uap->rgid, sizeof(cred->cr_rgid));
@@ -962,6 +1130,7 @@ getresgid(p, uap)
if (uap->sgid)
error3 = copyout((caddr_t)&cred->cr_svgid,
(caddr_t)uap->sgid, sizeof(cred->cr_svgid));
+ mtx_unlock(&Giant);
return error1 ? error1 : (error2 ? error2 : error3);
}
@@ -989,23 +1158,31 @@ issetugid(p, uap)
return (0);
}
+/*
+ * MPSAFE
+ */
int
__setugid(p, uap)
struct proc *p;
struct __setugid_args *uap;
{
-
#ifdef REGRESSION
+ int error = 0;
+
+ mtx_lock(&Giant);
switch (uap->flag) {
case 0:
p->p_flag &= ~P_SUGID;
- return (0);
+ break;
case 1:
p->p_flag |= P_SUGID;
- return (0);
+ break;
default:
- return (EINVAL);
+ error = EINVAL;
+ break;
}
+ mtx_unlock(&Giant);
+ return (error);
#else /* !REGRESSION */
return (ENOSYS);
#endif /* !REGRESSION */
@@ -1384,17 +1561,24 @@ struct getlogin_args {
u_int namelen;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
getlogin(p, uap)
struct proc *p;
struct getlogin_args *uap;
{
+ int error;
+ mtx_lock(&Giant);
if (uap->namelen > MAXLOGNAME)
uap->namelen = MAXLOGNAME;
- return (copyout((caddr_t) p->p_pgrp->pg_session->s_login,
- (caddr_t) uap->namebuf, uap->namelen));
+ error = copyout((caddr_t) p->p_pgrp->pg_session->s_login,
+ (caddr_t) uap->namebuf, uap->namelen);
+ mtx_unlock(&Giant);
+ return(error);
}
/*
@@ -1405,6 +1589,9 @@ struct setlogin_args {
char *namebuf;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
setlogin(p, uap)
@@ -1414,15 +1601,19 @@ setlogin(p, uap)
int error;
char logintmp[MAXLOGNAME];
+ mtx_lock(&Giant);
if ((error = suser_xxx(0, p, PRISON_ROOT)))
- return (error);
+ goto done2;
error = copyinstr((caddr_t) uap->namebuf, (caddr_t) logintmp,
sizeof(logintmp), (size_t *)0);
- if (error == ENAMETOOLONG)
+ if (error == ENAMETOOLONG) {
error = EINVAL;
- else if (!error)
+ } else if (!error) {
(void) memcpy(p->p_pgrp->pg_session->s_login, logintmp,
sizeof(logintmp));
+ }
+done2:
+ mtx_unlock(&Giant);
return (error);
}
diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c
index 9a27e0a..c3c39fe 100644
--- a/sys/kern/kern_resource.c
+++ b/sys/kern/kern_resource.c
@@ -80,6 +80,9 @@ struct getpriority_args {
int who;
};
#endif
+/*
+ * MPSAFE
+ */
int
getpriority(curp, uap)
struct proc *curp;
@@ -87,9 +90,11 @@ getpriority(curp, uap)
{
register struct proc *p;
register int low = PRIO_MAX + 1;
+ int error = 0;
- switch (uap->which) {
+ mtx_lock(&Giant);
+ switch (uap->which) {
case PRIO_PROCESS:
if (uap->who == 0)
low = curp->p_nice;
@@ -130,12 +135,14 @@ getpriority(curp, uap)
break;
default:
- return (EINVAL);
+ error = EINVAL;
+ break;
}
- if (low == PRIO_MAX + 1)
- return (ESRCH);
+ if (low == PRIO_MAX + 1 && error == 0)
+ error = ESRCH;
curp->p_retval[0] = low;
- return (0);
+ mtx_unlock(&Giant);
+ return (error);
}
#ifndef _SYS_SYSPROTO_H_
@@ -145,6 +152,9 @@ struct setpriority_args {
int prio;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
setpriority(curp, uap)
@@ -154,8 +164,9 @@ setpriority(curp, uap)
register struct proc *p;
int found = 0, error = 0;
- switch (uap->which) {
+ mtx_lock(&Giant);
+ switch (uap->which) {
case PRIO_PROCESS:
if (uap->who == 0)
error = donice(curp, curp, uap->prio);
@@ -200,10 +211,12 @@ setpriority(curp, uap)
break;
default:
- return (EINVAL);
+ error = EINVAL;
+ break;
}
- if (found == 0)
- return (ESRCH);
+ if (found == 0 && error == 0)
+ error = ESRCH;
+ mtx_unlock(&Giant);
return (error);
}
@@ -240,6 +253,9 @@ struct rtprio_args {
* Set realtime priority
*/
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
rtprio(curp, uap)
@@ -250,14 +266,19 @@ rtprio(curp, uap)
struct rtprio rtp;
int error;
+ mtx_lock(&Giant);
+
if (uap->pid == 0) {
p = curp;
PROC_LOCK(p);
- } else
+ } else {
p = pfind(uap->pid);
+ }
- if (p == NULL)
- return (ESRCH);
+ if (p == NULL) {
+ error = ESRCH;
+ goto done2;
+ }
switch (uap->function) {
case RTP_LOOKUP:
@@ -300,6 +321,8 @@ rtprio(curp, uap)
break;
}
PROC_UNLOCK(p);
+done2:
+ mtx_unlock(&Giant);
return (error);
}
@@ -355,6 +378,9 @@ struct osetrlimit_args {
struct orlimit *rlp;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
osetrlimit(p, uap)
@@ -370,7 +396,10 @@ osetrlimit(p, uap)
return (error);
lim.rlim_cur = olim.rlim_cur;
lim.rlim_max = olim.rlim_max;
- return (dosetrlimit(p, uap->which, &lim));
+ mtx_lock(&Giant);
+ error = dosetrlimit(p, uap->which, &lim);
+ mtx_unlock(&Giant);
+ return (error);
}
#ifndef _SYS_SYSPROTO_H_
@@ -379,6 +408,9 @@ struct ogetrlimit_args {
struct orlimit *rlp;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
ogetrlimit(p, uap)
@@ -386,16 +418,20 @@ ogetrlimit(p, uap)
register struct ogetrlimit_args *uap;
{
struct orlimit olim;
+ int error;
if (uap->which >= RLIM_NLIMITS)
return (EINVAL);
+ mtx_lock(&Giant);
olim.rlim_cur = p->p_rlimit[uap->which].rlim_cur;
if (olim.rlim_cur == -1)
olim.rlim_cur = 0x7fffffff;
olim.rlim_max = p->p_rlimit[uap->which].rlim_max;
if (olim.rlim_max == -1)
olim.rlim_max = 0x7fffffff;
- return (copyout((caddr_t)&olim, (caddr_t)uap->rlp, sizeof(olim)));
+ error = copyout((caddr_t)&olim, (caddr_t)uap->rlp, sizeof(olim));
+ mtx_unlock(&Giant);
+ return (error);
}
#endif /* COMPAT_43 || COMPAT_SUNOS */
@@ -405,6 +441,9 @@ struct __setrlimit_args {
struct rlimit *rlp;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
setrlimit(p, uap)
@@ -417,7 +456,10 @@ setrlimit(p, uap)
if ((error =
copyin((caddr_t)uap->rlp, (caddr_t)&alim, sizeof (struct rlimit))))
return (error);
- return (dosetrlimit(p, uap->which, &alim));
+ mtx_lock(&Giant);
+ error = dosetrlimit(p, uap->which, &alim);
+ mtx_unlock(&Giant);
+ return (error);
}
int
@@ -531,17 +573,24 @@ struct __getrlimit_args {
struct rlimit *rlp;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
getrlimit(p, uap)
struct proc *p;
register struct __getrlimit_args *uap;
{
+ int error;
if (uap->which >= RLIM_NLIMITS)
return (EINVAL);
- return (copyout((caddr_t)&p->p_rlimit[uap->which], (caddr_t)uap->rlp,
- sizeof (struct rlimit)));
+ mtx_lock(&Giant);
+ error = copyout((caddr_t)&p->p_rlimit[uap->which], (caddr_t)uap->rlp,
+ sizeof (struct rlimit));
+ mtx_unlock(&Giant);
+ return(error);
}
/*
@@ -645,6 +694,9 @@ struct getrusage_args {
struct rusage *rusage;
};
#endif
+/*
+ * MPSAFE
+ */
/* ARGSUSED */
int
getrusage(p, uap)
@@ -652,9 +704,11 @@ getrusage(p, uap)
register struct getrusage_args *uap;
{
register struct rusage *rup;
+ int error = 0;
- switch (uap->who) {
+ mtx_lock(&Giant);
+ switch (uap->who) {
case RUSAGE_SELF:
rup = &p->p_stats->p_ru;
mtx_lock_spin(&sched_lock);
@@ -667,10 +721,16 @@ getrusage(p, uap)
break;
default:
- return (EINVAL);
+ rup = NULL;
+ error = EINVAL;
+ break;
+ }
+ mtx_unlock(&Giant);
+ if (error == 0) {
+ error = copyout((caddr_t)rup, (caddr_t)uap->rusage,
+ sizeof (struct rusage));
}
- return (copyout((caddr_t)rup, (caddr_t)uap->rusage,
- sizeof (struct rusage)));
+ return(error);
}
void
diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c
index 1afa80f..90b3642 100644
--- a/sys/kern/kern_shutdown.c
+++ b/sys/kern/kern_shutdown.c
@@ -131,21 +131,23 @@ shutdown_conf(void *unused)
SYSINIT(shutdown_conf, SI_SUB_INTRINSIC, SI_ORDER_ANY, shutdown_conf, NULL)
-/* ARGSUSED */
-
/*
* The system call that results in a reboot
+ *
+ * MPSAFE
*/
+/* ARGSUSED */
int
reboot(struct proc *p, struct reboot_args *uap)
{
int error;
- if ((error = suser(p)))
- return (error);
-
- boot(uap->opt);
- return (0);
+ mtx_lock(&Giant);
+ if ((error = suser(p)) == 0) {
+ boot(uap->opt);
+ }
+ mtx_unlock(&Giant);
+ return (error);
}
/*
@@ -565,14 +567,27 @@ static u_int panic_cpu = NOCPU;
* Panic is called on unresolvable fatal errors. It prints "panic: mesg",
* and then reboots. If we are called twice, then we avoid trying to sync
* the disks as this often leads to recursive panics.
+ *
+ * MPSAFE
*/
void
panic(const char *fmt, ...)
{
int bootopt;
+ int holding_giant = 0;
va_list ap;
static char buf[256];
+#if 0
+ /*
+ * We must hold Giant when entering a panic
+ */
+ if (!mtx_owned(&Giant)) {
+ mtx_lock(&Giant);
+ holding_giant = 1;
+ }
+#endif
+
#ifdef SMP
/*
* We don't want multiple CPU's to panic at the same time, so we
@@ -580,11 +595,13 @@ panic(const char *fmt, ...)
* panic_cpu if we are spinning in case the panic on the first
* CPU is canceled.
*/
- if (panic_cpu != PCPU_GET(cpuid))
+ if (panic_cpu != PCPU_GET(cpuid)) {
while (atomic_cmpset_int(&panic_cpu, NOCPU,
- PCPU_GET(cpuid)) == 0)
+ PCPU_GET(cpuid)) == 0) {
while (panic_cpu != NOCPU)
; /* nothing */
+ }
+ }
#endif
bootopt = RB_AUTOBOOT | RB_DUMP;
@@ -616,6 +633,8 @@ panic(const char *fmt, ...)
#ifdef SMP
atomic_store_rel_int(&panic_cpu, NOCPU);
#endif
+ if (holding_giant)
+ mtx_unlock(&Giant);
return;
}
#endif
OpenPOWER on IntegriCloud