From owner-freebsd-sparc Thu Jan 23 6:41: 3 2003 Delivered-To: freebsd-sparc@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id ADFEF37B401; Thu, 23 Jan 2003 06:41:00 -0800 (PST) Received: from mailhub.fokus.gmd.de (mailhub.fokus.gmd.de [193.174.154.14]) by mx1.FreeBSD.org (Postfix) with ESMTP id 54E5343ED8; Thu, 23 Jan 2003 06:40:57 -0800 (PST) (envelope-from hbb@catssrv.fokus.gmd.de) Received: from catssrv.fokus.gmd.de (catssrv [192.168.229.23]) by mailhub.fokus.gmd.de (8.11.6/8.11.6) with ESMTP id h0NEeqi04874; Thu, 23 Jan 2003 15:40:52 +0100 (MET) Received: from catssrv.fokus.gmd.de (localhost [127.0.0.1]) by catssrv.fokus.gmd.de (8.12.6/8.12.6) with ESMTP id h0NEeqF2000640; Thu, 23 Jan 2003 15:40:52 +0100 (CET) (envelope-from hbb@catssrv.fokus.gmd.de) Received: (from root@localhost) by catssrv.fokus.gmd.de (8.12.6/8.12.6/Submit) id h0NEeqZ9000639; Thu, 23 Jan 2003 15:40:52 +0100 (CET) (envelope-from hbb) Date: Thu, 23 Jan 2003 15:40:52 +0100 (CET) Message-Id: <200301231440.h0NEeqZ9000639@catssrv.fokus.gmd.de> To: FreeBSD-gnats-submit@freebsd.org Subject: td_wmesg not cleared leads to panic when doing 'ps ax' From: Hartmut Brandt Reply-To: Hartmut Brandt Cc: sparc@freebsd.org X-send-pr-version: 3.113 X-GNATS-Notify: Sender: owner-freebsd-sparc@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org >Submitter-Id: current-users >Originator: Hartmut Brandt >Organization: >Confidential: no >Synopsis: td_wmesg not cleared leads to panic when doing 'ps ax' >Severity: serious >Priority: high >Category: kern >Class: sw-bug >Release: FreeBSD 5.0-CURRENT sparc64 >Environment: System: FreeBSD catssrv.fokus.gmd.de 5.0-CURRENT FreeBSD 5.0-CURRENT #17: Thu Jan 23 15:26:01 CET 2003 hbb@catssrv.fokus.gmd.de:/opt/obj/usr/src/sys/CATSSRV sparc64 >Description: The field td_wmesg of struct thread holds a pointer to a constant string and is set, when a thread calls either msleep or waits on a condition variable. When the thread continues, this fields is not cleared. When the msleep or cv_wait was called from a module, that is unloaded, the pointer in td_wmesg appears to become invalid. When now someone retrieves the process table via sysctl, then the kernel handler for this sysctl may access the now invalid pointer. On the SPARC this leads to a panic. i386 probably simply uses an invalid string (at least I have not seen that panic there). >How-To-Repeat: On the sparc: 1. load an interface driver that uses cv_wait or msleep. 2. unload the driver via kldunload 3. ps ax leads to an immediate crash. >Fix: Apply the attached patch. This sets td_wmesg to NULL when an msleep exits either via the timeout or because of wakeup. It sets also td_wmesg to NULL when a thread is remove from the wait queue of a condition variable. Index: sys/kern/kern_condvar.c =================================================================== RCS file: /home/cvs/freebsd/src/sys/kern/kern_condvar.c,v retrieving revision 1.35 diff -c -r1.35 kern_condvar.c *** sys/kern/kern_condvar.c 28 Dec 2002 01:23:07 -0000 1.35 --- sys/kern/kern_condvar.c 23 Jan 2003 14:31:51 -0000 *************** *** 535,540 **** --- 535,541 ---- if ((cvp = td->td_wchan) != NULL && td->td_flags & TDF_CVWAITQ) { TAILQ_REMOVE(&cvp->cv_waitq, td, td_slpq); td->td_flags &= ~TDF_CVWAITQ; + td->td_wmesg = NULL; TD_CLR_ON_SLEEPQ(td); } } Index: sys/kern/kern_synch.c =================================================================== RCS file: /home/cvs/freebsd/src/sys/kern/kern_synch.c,v retrieving revision 1.209 diff -c -r1.209 kern_synch.c *** sys/kern/kern_synch.c 28 Dec 2002 01:23:07 -0000 1.209 --- sys/kern/kern_synch.c 23 Jan 2003 14:31:51 -0000 *************** *** 330,335 **** --- 330,336 ---- TAILQ_REMOVE(&slpque[LOOKUP(td->td_wchan)], td, td_slpq); TD_CLR_ON_SLEEPQ(td); td->td_flags |= TDF_TIMEOUT; + td->td_wmesg = NULL; } else { td->td_flags |= TDF_TIMOFAIL; } *************** *** 374,379 **** --- 375,381 ---- if (TD_ON_SLEEPQ(td)) { TAILQ_REMOVE(&slpque[LOOKUP(td->td_wchan)], td, td_slpq); TD_CLR_ON_SLEEPQ(td); + td->td_wmesg = NULL; } mtx_unlock_spin(&sched_lock); } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-sparc" in the body of the message