Bug in kse_switchin()?
Daniel Eischen
deischen at freebsd.org
Thu Sep 23 04:25:03 PDT 2004
On Thu, 23 Sep 2004, Andrew Belashov wrote:
> Hello!
>
> I long time work on libkse library for FreeBSD/sparc64. Some work is done.
> Recently I have found a bug in kernel.
>
> Here details.
>
> From sys/kern/kern_kse.c:
> ---------------------------------------------------------------------------
> 1 int
> 2 kse_switchin(struct thread *td, struct kse_switchin_args *uap)
> 3 {
> 4 struct kse_thr_mailbox tmbx;
> 5 struct kse_upcall *ku;
> 6 int error;
> 7
> 8 if ((ku = td->td_upcall) == NULL || TD_CAN_UNBIND(td))
> 9 return (EINVAL);
> 10 error = (uap->tmbx == NULL) ? EINVAL : 0;
> 11 if (!error)
> 12 error = copyin(uap->tmbx, &tmbx, sizeof(tmbx));
> 13 if (!error && (uap->flags & KSE_SWITCHIN_SETTMBX))
> 14 error = (suword(&ku->ku_mailbox->km_curthread,
> 15 (long)uap->tmbx) != 0 ? EINVAL : 0);
> 16 if (!error)
> 17 error = set_mcontext(td, &tmbx.tm_context.uc_mcontext);
> 18 if (!error) {
> 19 suword32(&uap->tmbx->tm_lwp, td->td_tid);
> 20 if (uap->flags & KSE_SWITCHIN_SETTMBX) {
> 21 td->td_mailbox = uap->tmbx;
> 22 td->td_pflags |= TDP_CAN_UNBIND;
> 23 }
> 24 if (td->td_proc->p_flag & P_TRACED) {
> 25 if (tmbx.tm_dflags & TMDF_SSTEP)
> 26 ptrace_single_step(td);
> 27 else
> 28 ptrace_clear_single_step(td);
> 29 if (tmbx.tm_dflags & TMDF_SUSPEND) {
> 30 mtx_lock_spin(&sched_lock);
> 31 /* fuword can block, check again */
> 32 if (td->td_upcall)
> 33 ku->ku_flags |= KUF_DOUPCALL;
> 34 mtx_unlock_spin(&sched_lock);
> 35 }
> 36 }
> 37 }
> 38 return ((error == 0) ? EJUSTRETURN : error);
> 39 }
> ---------------------------------------------------------------------------
>
> 1. On FreeBSD/sparc64 uap structure (line 2) is stored in trap stack frame, if number of
> syscall arguments is 6 or less (see: sys/sparc64/sparc64/trap.c).
>
> 2. set_mcontext() function overwriting trap stack frame for restore saved
> context (line 17).
>
> 3. uap structure used after overwriting by set_mcontext() in following lines:
> 19, 20, 21.
>
> Same problem in thr_create() (see sys/kern/kern_thr.c).
>
> Where bug?
> - In sparc64 specific core?
> - In kern/kern_kse.c and kern/kern_thr.c code?
Wouldn't you also see same behavior (bugs) in other things, like
getcontext(), setcontext(), and swapcontext() (kern_context.c)?
--
Dan Eischen
More information about the freebsd-sparc64
mailing list