Giant Pushdown. Saved the worst P4 tree breakage for last.

reboot() getpriority() setpriority() rtprio() osetrlimit() ogetrlimit()
    setrlimit() getrlimit() getrusage() getpid() getppid() getpgrp()
    getpgid() getsid() getgid() getegid() getgroups() setsid() setpgid()
    setuid() seteuid() setgid() setegid() setgroups() setreuid() setregid()
    setresuid() setresgid() getresuid() getresgid () __setugid() getlogin()
    setlogin() modnext() modfnext() modstat() modfind() kldload() kldunload()
    kldfind() kldnext() kldstat() kldfirstmod() kldsym() getdtablesize()
    dup2() dup() fcntl() close() ofstat() fstat() nfsstat() fpathconf()
    flock()
This commit is contained in:
Matthew Dillon 2001-09-01 19:04:37 +00:00
parent e619430f32
commit 835a82ee2d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=82749
6 changed files with 670 additions and 213 deletions

View File

@ -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 @@ dup2(p, uap)
*/
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);
}
/*

View File

@ -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;
if ((error = suser(p)) != 0)
return error;
mtx_lock(&Giant);
if ((error = suser(p)) != 0)
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 @@ kldload(struct proc* p, struct kldload_args* uap)
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);
}
/*

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
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;
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;
}
return (copyout((caddr_t)rup, (caddr_t)uap->rusage,
sizeof (struct rusage)));
mtx_unlock(&Giant);
if (error == 0) {
error = copyout((caddr_t)rup, (caddr_t)uap->rusage,
sizeof (struct rusage));
}
return(error);
}
void

View File

@ -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