diff options
-rw-r--r-- | sys/kern/kern_descrip.c | 240 | ||||
-rw-r--r-- | sys/kern/kern_linker.c | 80 | ||||
-rw-r--r-- | sys/kern/kern_module.c | 71 | ||||
-rw-r--r-- | sys/kern/kern_prot.c | 351 | ||||
-rw-r--r-- | sys/kern/kern_resource.c | 102 | ||||
-rw-r--r-- | sys/kern/kern_shutdown.c | 37 |
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 |