Some syscalls using set_mcontext can sneakily change parameters and later when those syscalls references parameters, they will wrongly use register values in mcontext_t. This problem is critical for thread related syscalls! Fix: Simple patch. See also amd64/amd64/trap.c revision 1.278. <http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/amd64/amd64/trap.c.diff?r1=1.277&r2=1.278> How-To-Repeat: Use following changes in kernel: --- debug.patch begins here --- --- sys/kern/kern_kse.c.orig Fri Oct 22 14:47:07 2004 +++ sys/kern/kern_kse.c Fri Oct 22 14:46:13 2004 @@ -140,8 +140,12 @@ kse_switchin(struct thread *td, struct k if (!error && (uap->flags & KSE_SWITCHIN_SETTMBX)) error = (suword(&ku->ku_mailbox->km_curthread, (long)uap->tmbx) != 0 ? EINVAL : 0); + TR2("thread_schedule_upcall: before set_mcontext: tmbx %p flags %d", + uap->tmbx, uap->flags); if (!error) error = set_mcontext(td, &tmbx.tm_context.uc_mcontext); + TR2("thread_schedule_upcall: after set_mcontext: tmbx %p flags %d", + uap->tmbx, uap->flags); if (!error) { suword32(&uap->tmbx->tm_lwp, td->td_tid); if (uap->flags & KSE_SWITCHIN_SETTMBX) { --- sys/sparc64/conf/GENERIC.orig Wed Sep 22 23:23:39 2004 +++ sys/sparc64/conf/GENERIC Fri Oct 22 15:00:49 2004 @@ -201,3 +201,7 @@ device firewire # FireWire bus code device sbp # SCSI over FireWire (Requires scbus and da) device fwe # Ethernet over FireWire (non-standard!) + +options KDB #Enable kernel debugger support +options DDB #Enable the kernel debugger +options GDB #Support remote GDB +options KTR +options KTR_COMPILE=(KTR_GEN|KTR_SMP|KTR_TRAP|KTR_INTR|KTR_SIG|KTR_PROC|KTR_SYSC) +options KTR_ENTRIES=8192 --- debug.patch ends here --- Run any simple threated program compiled with libkse. For example: --- hello_d.c begins here --- /**************************************************************************** * * Simple diff mode test. * * $FreeBSD: src/lib/libpthread/test/hello_d.c,v 1.1 2000/04/24 21:07:37 jasone Exp $ * ****************************************************************************/ #include <stdio.h> #include <string.h> #include <pthread.h> extern int _libkse_debug; void * entry(void * a_arg) { char *str = NULL; fprintf(stderr, "Hello world\n"); #if 0 *str = 'a'; #endif return NULL; } int main() { pthread_t thread; int error; pthread_attr_t attr; int scope; /* _libkse_debug = 1; */ error = pthread_attr_init(&attr); if (error) fprintf(stderr, "Error in pthread_attr_init(): %s\n", strerror(error)); error = pthread_attr_getscope(&attr, &scope); if (error) fprintf(stderr, "Error in pthread_attr_getscope(): %s\n", strerror(error)); printf("Default scope: %d\n", scope); #if 1 scope |= PTHREAD_SCOPE_SYSTEM; #endif printf("Set scope: %d\n", scope); error = pthread_attr_setscope(&attr, scope); if (error) fprintf(stderr, "Error in pthread_attr_setscope(): %s\n", strerror(error)); error = pthread_create(&thread, &attr, entry, NULL); if (error) fprintf(stderr, "Error in pthread_create(): %s\n", strerror(error)); error = pthread_join(thread, NULL); if (error) fprintf(stderr, "Error in pthread_join(): %s\n", strerror(error)); error = pthread_attr_destroy(&attr); if (error) fprintf(stderr, "Error in pthread_attr_destroy(): %s\n", strerror(error)); return 0; } --- hello_d.c ends here --- Go to kernel debugger by pressing Control-Alt-Esc and "show ktr". Compare arguments before and after set_mcontext.
State Changed From-To: open->closed It has been fixed on revision 1.9 of src/sys/sparc64/sparc64/trap.c. Thanks!
marius 2008-08-24 20:02:18 UTC FreeBSD src repository Modified files: sys/sparc64/sparc64 trap.c Log: SVN rev 182119 on 2008-08-24 20:02:18Z by marius MFamd64: r133413 In syscall, always make a copy of parameters from trapframe, this becauses some syscalls using set_mcontext can sneakily change parameters and later when those syscalls references parameters, they will wrongly use register values in mcontext_t. PR: 72998 MFC after: 3 days Revision Changes Path 1.92 +6 -9 src/sys/sparc64/sparc64/trap.c _______________________________________________ cvs-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/cvs-all To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
marius 2008-08-28 18:24:24 UTC FreeBSD src repository Modified files: (Branch: RELENG_7) sys/sparc64/sparc64 trap.c Log: SVN rev 182389 on 2008-08-28 18:24:24Z by marius MFC: r182119 MFamd64: r133413 In syscall, always make a copy of parameters from trapframe, this becauses some syscalls using set_mcontext can sneakily change parameters and later when those syscalls references parameters, they will wrongly use register values in mcontext_t. PR: 72998 Revision Changes Path 1.88.2.3 +6 -9 src/sys/sparc64/sparc64/trap.c _______________________________________________ cvs-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/cvs-all To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
marius 2008-08-28 18:24:27 UTC FreeBSD src repository Modified files: (Branch: RELENG_6) sys/sparc64/sparc64 trap.c Log: SVN rev 182390 on 2008-08-28 18:24:27Z by marius MFC: r182119 MFamd64: r133413 In syscall, always make a copy of parameters from trapframe, this becauses some syscalls using set_mcontext can sneakily change parameters and later when those syscalls references parameters, they will wrongly use register values in mcontext_t. PR: 72998 Revision Changes Path 1.74.2.4 +6 -9 src/sys/sparc64/sparc64/trap.c _______________________________________________ cvs-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/cvs-all To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"