Date: Fri, 22 Oct 2004 15:43:51 +0400 (MSD) From: Andrew Belashov <bel@orel.ru> To: FreeBSD-gnats-submit@FreeBSD.org Subject: sparc64/72998: [patch] set_mcontext() change syscalls parameters on sparc64 Message-ID: <200410221143.i9MBhpna088318@white.orel.ru> Resent-Message-ID: <200410221150.i9MBoDOO028436@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 72998 >Category: sparc64 >Synopsis: [patch] set_mcontext() change syscalls parameters on sparc64 >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-sparc64 >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Fri Oct 22 11:50:12 GMT 2004 >Closed-Date: >Last-Modified: >Originator: Andrew Belashov >Release: FreeBSD 5.3-BETA7 sparc64 >Organization: JSC CenterTelecom >Environment: System: FreeBSD bel.localdomain 5.3-BETA7 FreeBSD 5.3-BETA7 #11: Thu Oct 14 13:02:53 MSD 2004 bel@bel.localdomain:/usr/obj/usr/src/sys/SUNC3D sparc64 >Description: 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! >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. >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> --- sparc64_trap.patch begins here --- --- sys/sparc64/sparc64/trap.c.orig Thu Aug 5 09:42:43 2004 +++ sys/sparc64/sparc64/trap.c Fri Sep 24 10:09:06 2004 @@ -559,7 +559,8 @@ syscall(struct trapframe *tf) narg = callp->sy_narg & SYF_ARGMASK; if (narg <= regcnt) { - argp = &tf->tf_out[reg]; + argp = args; + bcopy(&tf->tf_out[reg], args, sizeof(args[0]) * regcnt); error = 0; } else { KASSERT(narg <= sizeof(args) / sizeof(args[0]), --- sparc64_trap.patch ends here --- >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200410221143.i9MBhpna088318>