From 835a82ee2d3ecab3628947d1788030d86b1b5c10 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Sat, 1 Sep 2001 19:04:37 +0000 Subject: [PATCH] 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() --- sys/kern/kern_descrip.c | 240 +++++++++++++++++++------- sys/kern/kern_linker.c | 82 ++++++--- sys/kern/kern_module.c | 71 +++++--- sys/kern/kern_prot.c | 351 ++++++++++++++++++++++++++++++--------- sys/kern/kern_resource.c | 102 +++++++++--- sys/kern/kern_shutdown.c | 37 ++++- 6 files changed, 670 insertions(+), 213 deletions(-) diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index d040690904df..a09c8c230260 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 @@ 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); } /* diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c index 48f414b2f4ac..7b5753bd51c1 100644 --- a/sys/kern/kern_linker.c +++ b/sys/kern/kern_linker.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -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); } /* diff --git a/sys/kern/kern_module.c b/sys/kern/kern_module.c index b9d35d7bb870..3fbdb723156e 100644 --- a/sys/kern/kern_module.c +++ b/sys/kern/kern_module.c @@ -36,6 +36,8 @@ #include #include #include +#include +#include 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 2802b01e6e61..baa73dd352f8 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 9a27e0a163c8..c3c39feb9ecb 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; + + 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 diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c index 1afa80fb0077..90b36428efbe 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