diff options
-rw-r--r-- | sys/kern/kern_sig.c | 170 | ||||
-rw-r--r-- | sys/kern/kern_sysctl.c | 39 | ||||
-rw-r--r-- | sys/kern/kern_time.c | 173 |
3 files changed, 287 insertions, 95 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 49e8307..16d2463 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -345,6 +345,9 @@ struct sigaction_args { struct sigaction *oact; }; #endif +/* + * MPSAFE + */ /* ARGSUSED */ int sigaction(p, uap) @@ -355,17 +358,21 @@ sigaction(p, uap) register struct sigaction *actp, *oactp; int error; + mtx_lock(&Giant); + actp = (uap->act != NULL) ? &act : NULL; oactp = (uap->oact != NULL) ? &oact : NULL; if (actp) { error = copyin(uap->act, actp, sizeof(act)); if (error) - return (error); + goto done2; } error = do_sigaction(p, uap->sig, actp, oactp, 0); if (oactp && !error) { error = copyout(oactp, uap->oact, sizeof(oact)); } +done2: + mtx_unlock(&Giant); return (error); } @@ -377,6 +384,9 @@ struct osigaction_args { struct osigaction *osa; }; #endif +/* + * MPSAFE + */ /* ARGSUSED */ int osigaction(p, uap) @@ -390,12 +400,16 @@ osigaction(p, uap) if (uap->signum <= 0 || uap->signum >= ONSIG) return (EINVAL); + nsap = (uap->nsa != NULL) ? &nsa : NULL; osap = (uap->osa != NULL) ? &osa : NULL; + + mtx_lock(&Giant); + if (nsap) { error = copyin(uap->nsa, &sa, sizeof(sa)); if (error) - return (error); + goto done2; nsap->sa_handler = sa.sa_handler; nsap->sa_flags = sa.sa_flags; OSIG2SIG(sa.sa_mask, nsap->sa_mask); @@ -407,6 +421,8 @@ osigaction(p, uap) SIG2OSIG(osap->sa_mask, sa.sa_mask); error = copyout(&sa, uap->osa, sizeof(sa)); } +done2: + mtx_unlock(&Giant); return (error); } #endif /* COMPAT_43 */ @@ -580,6 +596,9 @@ struct sigpending_args { sigset_t *set; }; #endif +/* + * MPSAFE + */ /* ARGSUSED */ int sigpending(p, uap) @@ -587,11 +606,15 @@ sigpending(p, uap) struct sigpending_args *uap; { sigset_t siglist; + int error; + mtx_lock(&Giant); PROC_LOCK(p); siglist = p->p_siglist; PROC_UNLOCK(p); - return (copyout(&siglist, uap->set, sizeof(sigset_t))); + mtx_unlock(&Giant); + error = copyout(&siglist, uap->set, sizeof(sigset_t)); + return(error); } #ifdef COMPAT_43 /* XXX - COMPAT_FBSD3 */ @@ -600,16 +623,20 @@ struct osigpending_args { int dummy; }; #endif +/* + * MPSAFE + */ /* ARGSUSED */ int osigpending(p, uap) struct proc *p; struct osigpending_args *uap; { - + mtx_lock(&Giant); PROC_LOCK(p); SIG2OSIG(p->p_siglist, p->p_retval[0]); PROC_UNLOCK(p); + mtx_unlock(&Giant); return (0); } #endif /* COMPAT_43 */ @@ -625,6 +652,9 @@ struct osigvec_args { struct sigvec *osv; }; #endif +/* + * MPSAFE + */ /* ARGSUSED */ int osigvec(p, uap) @@ -652,7 +682,9 @@ osigvec(p, uap) nsap->sa_flags |= SA_USERTRAMP; #endif } + mtx_lock(&Giant); error = do_sigaction(p, uap->signum, nsap, osap, 1); + mtx_unlock(&Giant); if (osap && !error) { vec.sv_handler = osap->sa_handler; SIG2OSIG(osap->sa_mask, vec.sv_mask); @@ -672,6 +704,9 @@ struct osigblock_args { int mask; }; #endif +/* + * MPSAFE + */ int osigblock(p, uap) register struct proc *p; @@ -681,10 +716,12 @@ osigblock(p, uap) OSIG2SIG(uap->mask, set); SIG_CANTMASK(set); + mtx_lock(&Giant); PROC_LOCK(p); SIG2OSIG(p->p_sigmask, p->p_retval[0]); SIGSETOR(p->p_sigmask, set); PROC_UNLOCK(p); + mtx_unlock(&Giant); return (0); } @@ -693,6 +730,9 @@ struct osigsetmask_args { int mask; }; #endif +/* + * MPSAFE + */ int osigsetmask(p, uap) struct proc *p; @@ -702,10 +742,12 @@ osigsetmask(p, uap) OSIG2SIG(uap->mask, set); SIG_CANTMASK(set); + mtx_lock(&Giant); PROC_LOCK(p); SIG2OSIG(p->p_sigmask, p->p_retval[0]); SIGSETLO(p->p_sigmask, set); PROC_UNLOCK(p); + mtx_unlock(&Giant); return (0); } #endif /* COMPAT_43 || COMPAT_SUNOS */ @@ -720,6 +762,9 @@ struct sigsuspend_args { const sigset_t *sigmask; }; #endif +/* + * MPSAFE + */ /* ARGSUSED */ int sigsuspend(p, uap) @@ -741,6 +786,7 @@ sigsuspend(p, uap) * save it here and mark the sigacts structure * to indicate this. */ + mtx_lock(&Giant); PROC_LOCK(p); ps = p->p_sigacts; p->p_oldsigmask = p->p_sigmask; @@ -751,6 +797,7 @@ sigsuspend(p, uap) while (msleep((caddr_t) ps, &p->p_mtx, PPAUSE|PCATCH, "pause", 0) == 0) /* void */; PROC_UNLOCK(p); + mtx_unlock(&Giant); /* always return EINTR rather than ERESTART... */ return (EINTR); } @@ -761,6 +808,9 @@ struct osigsuspend_args { osigset_t mask; }; #endif +/* + * MPSAFE + */ /* ARGSUSED */ int osigsuspend(p, uap) @@ -770,6 +820,7 @@ osigsuspend(p, uap) sigset_t mask; register struct sigacts *ps; + mtx_lock(&Giant); PROC_LOCK(p); ps = p->p_sigacts; p->p_oldsigmask = p->p_sigmask; @@ -780,6 +831,7 @@ osigsuspend(p, uap) while (msleep((caddr_t) ps, &p->p_mtx, PPAUSE|PCATCH, "opause", 0) == 0) /* void */; PROC_UNLOCK(p); + mtx_unlock(&Giant); /* always return EINTR rather than ERESTART... */ return (EINTR); } @@ -792,6 +844,9 @@ struct osigstack_args { struct sigstack *oss; }; #endif +/* + * MPSAFE + */ /* ARGSUSED */ int osigstack(p, uap) @@ -799,7 +854,9 @@ osigstack(p, uap) register struct osigstack_args *uap; { struct sigstack ss; - int error; + int error = 0; + + mtx_lock(&Giant); if (uap->oss != NULL) { PROC_LOCK(p); @@ -808,12 +865,12 @@ osigstack(p, uap) PROC_UNLOCK(p); error = copyout(&ss, uap->oss, sizeof(struct sigstack)); if (error) - return (error); + goto done2; } if (uap->nss != NULL) { if ((error = copyin(uap->nss, &ss, sizeof(ss))) != 0) - return (error); + goto done2; PROC_LOCK(p); p->p_sigstk.ss_sp = ss.ss_sp; p->p_sigstk.ss_size = 0; @@ -821,7 +878,9 @@ osigstack(p, uap) p->p_flag |= P_ALTSTACK; PROC_UNLOCK(p); } - return (0); +done2: + mtx_unlock(&Giant); + return (error); } #endif /* COMPAT_43 || COMPAT_SUNOS */ @@ -831,6 +890,9 @@ struct sigaltstack_args { stack_t *oss; }; #endif +/* + * MPSAFE + */ /* ARGSUSED */ int sigaltstack(p, uap) @@ -838,7 +900,10 @@ sigaltstack(p, uap) register struct sigaltstack_args *uap; { stack_t ss; - int error, oonstack; + int oonstack; + int error = 0; + + mtx_lock(&Giant); oonstack = sigonstack(cpu_getstack(p)); @@ -849,19 +914,25 @@ sigaltstack(p, uap) ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; PROC_UNLOCK(p); if ((error = copyout(&ss, uap->oss, sizeof(stack_t))) != 0) - return (error); + goto done2; } if (uap->ss != NULL) { - if (oonstack) - return (EPERM); + if (oonstack) { + error = EPERM; + goto done2; + } if ((error = copyin(uap->ss, &ss, sizeof(ss))) != 0) - return (error); - if ((ss.ss_flags & ~SS_DISABLE) != 0) - return (EINVAL); + goto done2; + if ((ss.ss_flags & ~SS_DISABLE) != 0) { + error = EINVAL; + goto done2; + } if (!(ss.ss_flags & SS_DISABLE)) { - if (ss.ss_size < p->p_sysent->sv_minsigstksz) - return (ENOMEM); + if (ss.ss_size < p->p_sysent->sv_minsigstksz) { + error = ENOMEM; + goto done2; + } PROC_LOCK(p); p->p_sigstk = ss; p->p_flag |= P_ALTSTACK; @@ -872,7 +943,9 @@ sigaltstack(p, uap) PROC_UNLOCK(p); } } - return (0); +done2: + mtx_unlock(&Giant); + return (error); } /* @@ -948,6 +1021,9 @@ struct kill_args { int signum; }; #endif +/* + * MPSAFE + */ /* ARGSUSED */ int kill(cp, uap) @@ -955,31 +1031,40 @@ kill(cp, uap) register struct kill_args *uap; { register struct proc *p; + int error = 0; if ((u_int)uap->signum > _SIG_MAXSIG) return (EINVAL); + + mtx_lock(&Giant); if (uap->pid > 0) { /* kill single process */ - if ((p = pfind(uap->pid)) == NULL) - return (ESRCH); - if (p_cansignal(cp, p, uap->signum)) { + if ((p = pfind(uap->pid)) == NULL) { + error = ESRCH; + } else if (p_cansignal(cp, p, uap->signum)) { + PROC_UNLOCK(p); + error = EPERM; + } else { + if (uap->signum) + psignal(p, uap->signum); PROC_UNLOCK(p); - return (EPERM); + error = 0; + } + } else { + switch (uap->pid) { + case -1: /* broadcast signal */ + error = killpg1(cp, uap->signum, 0, 1); + break; + case 0: /* signal own process group */ + error = killpg1(cp, uap->signum, 0, 0); + break; + default: /* negative explicit process group */ + error = killpg1(cp, uap->signum, -uap->pid, 0); + break; } - if (uap->signum) - psignal(p, uap->signum); - PROC_UNLOCK(p); - return (0); - } - switch (uap->pid) { - case -1: /* broadcast signal */ - return (killpg1(cp, uap->signum, 0, 1)); - case 0: /* signal own process group */ - return (killpg1(cp, uap->signum, 0, 0)); - default: /* negative explicit process group */ - return (killpg1(cp, uap->signum, -uap->pid, 0)); } - /* NOTREACHED */ + mtx_unlock(&Giant); + return(error); } #if defined(COMPAT_43) || defined(COMPAT_SUNOS) @@ -989,16 +1074,23 @@ struct okillpg_args { int signum; }; #endif +/* + * MPSAFE + */ /* ARGSUSED */ int okillpg(p, uap) struct proc *p; register struct okillpg_args *uap; { + int error; if ((u_int)uap->signum > _SIG_MAXSIG) return (EINVAL); - return (killpg1(p, uap->signum, uap->pgid, 0)); + mtx_lock(&Giant); + error = killpg1(p, uap->signum, uap->pgid, 0); + mtx_unlock(&Giant); + return (error); } #endif /* COMPAT_43 || COMPAT_SUNOS */ @@ -1852,16 +1944,20 @@ struct nosys_args { int dummy; }; #endif +/* + * MPSAFE + */ /* ARGSUSED */ int nosys(p, args) struct proc *p; struct nosys_args *args; { - + mtx_lock(&Giant); PROC_LOCK(p); psignal(p, SIGSYS); PROC_UNLOCK(p); + mtx_unlock(&Giant); return (EINVAL); } diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 6397893..ce5ba3d 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -48,6 +48,8 @@ #include <sys/sysctl.h> #include <sys/malloc.h> #include <sys/proc.h> +#include <sys/lock.h> +#include <sys/mutex.h> #include <sys/sysproto.h> #include <vm/vm.h> #include <vm/vm_extern.h> @@ -1060,10 +1062,13 @@ struct sysctl_args { }; #endif +/* + * MPSAFE + */ int __sysctl(struct proc *p, struct sysctl_args *uap) { - int error, i, name[CTL_MAXNAME]; + int error, name[CTL_MAXNAME]; size_t j; if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) @@ -1073,16 +1078,20 @@ __sysctl(struct proc *p, struct sysctl_args *uap) if (error) return (error); + mtx_lock(&Giant); + error = userland_sysctl(p, name, uap->namelen, uap->old, uap->oldlenp, 0, uap->new, uap->newlen, &j); if (error && error != ENOMEM) - return (error); + goto done2; if (uap->oldlenp) { - i = copyout(&j, uap->oldlenp, sizeof(j)); + int i = copyout(&j, uap->oldlenp, sizeof(j)); if (i) - return (i); + error = i; } +done2: + mtx_unlock(&Giant); return (error); } @@ -1232,6 +1241,9 @@ struct getkerninfo_args { }; #endif +/* + * MPSAFE + */ int ogetkerninfo(struct proc *p, struct getkerninfo_args *uap) { @@ -1239,6 +1251,8 @@ ogetkerninfo(struct proc *p, struct getkerninfo_args *uap) size_t size; u_int needed = 0; + mtx_lock(&Giant); + switch (uap->op & 0xff00) { case KINFO_RT: @@ -1362,14 +1376,17 @@ ogetkerninfo(struct proc *p, struct getkerninfo_args *uap) } default: - return (EOPNOTSUPP); + error = EOPNOTSUPP; + break; } - if (error) - return (error); - p->p_retval[0] = needed ? needed : size; - if (uap->size) - error = copyout((caddr_t)&size, (caddr_t)uap->size, - sizeof(size)); + if (error == 0) { + p->p_retval[0] = needed ? needed : size; + if (uap->size) { + error = copyout((caddr_t)&size, (caddr_t)uap->size, + sizeof(size)); + } + } + mtx_unlock(&Giant); return (error); } #endif /* COMPAT_43 */ diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index 60a2563..545479d 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -146,6 +146,9 @@ struct clock_gettime_args { }; #endif +/* + * MPSAFE + */ /* ARGSUSED */ int clock_gettime(p, uap) @@ -156,7 +159,9 @@ clock_gettime(p, uap) if (SCARG(uap, clock_id) != CLOCK_REALTIME) return (EINVAL); + mtx_lock(&Giant); nanotime(&ats); + mtx_unlock(&Giant); return (copyout(&ats, SCARG(uap, tp), sizeof(ats))); } @@ -167,6 +172,9 @@ struct clock_settime_args { }; #endif +/* + * MPSAFE + */ /* ARGSUSED */ int clock_settime(p, uap) @@ -177,19 +185,25 @@ clock_settime(p, uap) struct timespec ats; int error; + mtx_lock(&Giant); if ((error = suser(p)) != 0) - return (error); - if (SCARG(uap, clock_id) != CLOCK_REALTIME) - return (EINVAL); + goto done2; + if (SCARG(uap, clock_id) != CLOCK_REALTIME) { + error = EINVAL; + goto done2; + } if ((error = copyin(SCARG(uap, tp), &ats, sizeof(ats))) != 0) - return (error); - if (ats.tv_nsec < 0 || ats.tv_nsec >= 1000000000) - return (EINVAL); + goto done2; + if (ats.tv_nsec < 0 || ats.tv_nsec >= 1000000000) { + error = EINVAL; + goto done2; + } /* XXX Don't convert nsec->usec and back */ TIMESPEC_TO_TIMEVAL(&atv, &ats); - if ((error = settime(&atv))) - return (error); - return (0); + error = settime(&atv); +done2: + mtx_unlock(&Giant); + return (error); } #ifndef _SYS_SYSPROTO_H_ @@ -266,6 +280,9 @@ struct nanosleep_args { }; #endif +/* + * MPSAFE + */ /* ARGSUSED */ int nanosleep(p, uap) @@ -273,21 +290,30 @@ nanosleep(p, uap) struct nanosleep_args *uap; { struct timespec rmt, rqt; - int error, error2; + int error; error = copyin(SCARG(uap, rqtp), &rqt, sizeof(rqt)); if (error) return (error); - if (SCARG(uap, rmtp)) + + mtx_lock(&Giant); + if (SCARG(uap, rmtp)) { if (!useracc((caddr_t)SCARG(uap, rmtp), sizeof(rmt), - VM_PROT_WRITE)) - return (EFAULT); + VM_PROT_WRITE)) { + error = EFAULT; + goto done2; + } + } error = nanosleep1(p, &rqt, &rmt); if (error && SCARG(uap, rmtp)) { + int error2; + error2 = copyout(&rmt, SCARG(uap, rmtp), sizeof(rmt)); if (error2) /* XXX shouldn't happen, did useracc() above */ - return (error2); + error = error2; } +done2: + mtx_unlock(&Giant); return (error); } @@ -297,6 +323,9 @@ struct gettimeofday_args { struct timezone *tzp; }; #endif +/* + * MPSAFE + */ /* ARGSUSED */ int gettimeofday(p, uap) @@ -306,15 +335,20 @@ gettimeofday(p, uap) struct timeval atv; int error = 0; + mtx_lock(&Giant); if (uap->tp) { microtime(&atv); if ((error = copyout((caddr_t)&atv, (caddr_t)uap->tp, - sizeof (atv)))) - return (error); + sizeof (atv)))) { + goto done2; + } } - if (uap->tzp) + if (uap->tzp) { error = copyout((caddr_t)&tz, (caddr_t)uap->tzp, sizeof (tz)); + } +done2: + mtx_unlock(&Giant); return (error); } @@ -324,6 +358,9 @@ struct settimeofday_args { struct timezone *tzp; }; #endif +/* + * MPSAFE + */ /* ARGSUSED */ int settimeofday(p, uap) @@ -332,26 +369,34 @@ settimeofday(p, uap) { struct timeval atv; struct timezone atz; - int error; + int error = 0; + + mtx_lock(&Giant); if ((error = suser(p))) - return (error); + goto done2; /* Verify all parameters before changing time. */ if (uap->tv) { if ((error = copyin((caddr_t)uap->tv, (caddr_t)&atv, - sizeof(atv)))) - return (error); - if (atv.tv_usec < 0 || atv.tv_usec >= 1000000) - return (EINVAL); + sizeof(atv)))) { + goto done2; + } + if (atv.tv_usec < 0 || atv.tv_usec >= 1000000) { + error = EINVAL; + goto done2; + } } if (uap->tzp && - (error = copyin((caddr_t)uap->tzp, (caddr_t)&atz, sizeof(atz)))) - return (error); + (error = copyin((caddr_t)uap->tzp, (caddr_t)&atz, sizeof(atz)))) { + goto done2; + } if (uap->tv && (error = settime(&atv))) - return (error); + goto done2; if (uap->tzp) tz = atz; - return (0); +done2: + mtx_unlock(&Giant); + return (error); } int tickdelta; /* current clock skew, us. per tick */ @@ -364,6 +409,9 @@ struct adjtime_args { struct timeval *olddelta; }; #endif +/* + * MPSAFE + */ /* ARGSUSED */ int adjtime(p, uap) @@ -374,11 +422,14 @@ adjtime(p, uap) register long ndelta, ntickdelta, odelta; int s, error; + mtx_lock(&Giant); + if ((error = suser(p))) - return (error); - if ((error = - copyin((caddr_t)uap->delta, (caddr_t)&atv, sizeof(struct timeval)))) - return (error); + goto done2; + error = copyin((caddr_t)uap->delta, (caddr_t)&atv, + sizeof(struct timeval)); + if (error) + goto done2; /* * Compute the total correction and the rate at which to apply it. @@ -414,7 +465,9 @@ adjtime(p, uap) (void) copyout((caddr_t)&atv, (caddr_t)uap->olddelta, sizeof(struct timeval)); } - return (0); +done2: + mtx_unlock(&Giant); + return (error); } /* @@ -444,6 +497,9 @@ struct getitimer_args { struct itimerval *itv; }; #endif +/* + * MPSAFE + */ /* ARGSUSED */ int getitimer(p, uap) @@ -453,9 +509,13 @@ getitimer(p, uap) struct timeval ctv; struct itimerval aitv; int s; + int error; if (uap->which > ITIMER_PROF) return (EINVAL); + + mtx_lock(&Giant); + s = splclock(); /* XXX still needed ? */ if (uap->which == ITIMER_REAL) { /* @@ -472,11 +532,14 @@ getitimer(p, uap) else timevalsub(&aitv.it_value, &ctv); } - } else + } else { aitv = p->p_stats->p_timer[uap->which]; + } splx(s); - return (copyout((caddr_t)&aitv, (caddr_t)uap->itv, - sizeof (struct itimerval))); + error = copyout((caddr_t)&aitv, (caddr_t)uap->itv, + sizeof (struct itimerval)); + mtx_unlock(&Giant); + return(error); } #ifndef _SYS_SYSPROTO_H_ @@ -485,6 +548,9 @@ struct setitimer_args { struct itimerval *itv, *oitv; }; #endif +/* + * MPSAFE + */ /* ARGSUSED */ int setitimer(p, uap) @@ -494,7 +560,7 @@ setitimer(p, uap) struct itimerval aitv; struct timeval ctv; register struct itimerval *itvp; - int s, error; + int s, error = 0; if (uap->which > ITIMER_PROF) return (EINVAL); @@ -502,17 +568,27 @@ setitimer(p, uap) if (itvp && (error = copyin((caddr_t)itvp, (caddr_t)&aitv, sizeof(struct itimerval)))) return (error); + + mtx_lock(&Giant); + if ((uap->itv = uap->oitv) && - (error = getitimer(p, (struct getitimer_args *)uap))) - return (error); - if (itvp == 0) - return (0); - if (itimerfix(&aitv.it_value)) - return (EINVAL); - if (!timevalisset(&aitv.it_value)) + (error = getitimer(p, (struct getitimer_args *)uap))) { + goto done2; + } + if (itvp == 0) { + error = 0; + goto done2; + } + if (itimerfix(&aitv.it_value)) { + error = EINVAL; + goto done2; + } + if (!timevalisset(&aitv.it_value)) { timevalclear(&aitv.it_interval); - else if (itimerfix(&aitv.it_interval)) - return (EINVAL); + } else if (itimerfix(&aitv.it_interval)) { + error = EINVAL; + goto done2; + } s = splclock(); /* XXX: still needed ? */ if (uap->which == ITIMER_REAL) { if (timevalisset(&p->p_realtimer.it_value)) @@ -523,10 +599,13 @@ setitimer(p, uap) getmicrouptime(&ctv); timevaladd(&aitv.it_value, &ctv); p->p_realtimer = aitv; - } else + } else { p->p_stats->p_timer[uap->which] = aitv; + } splx(s); - return (0); +done2: + mtx_unlock(&Giant); + return (error); } /* |