From nobody@www.freebsd.org  Sun May 12 16:17:45 2002
Return-Path: <nobody@www.freebsd.org>
Received: from nwww.freebsd.org (www.FreeBSD.org [216.136.204.117])
	by hub.freebsd.org (Postfix) with ESMTP id B6CC137B403
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 12 May 2002 16:17:44 -0700 (PDT)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by nwww.freebsd.org (8.12.2/8.12.2) with ESMTP id g4CNHihG067492
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 12 May 2002 16:17:44 -0700 (PDT)
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.12.2/8.12.2/Submit) id g4CNHiKH067491;
	Sun, 12 May 2002 16:17:44 -0700 (PDT)
Message-Id: <200205122317.g4CNHiKH067491@www.freebsd.org>
Date: Sun, 12 May 2002 16:17:44 -0700 (PDT)
From: Marcel Moolenaar <marcel@xcllnt.net>
To: freebsd-gnats-submit@FreeBSD.org
Subject: tcsh calls malloc() from signal handler without serialization
X-Send-Pr-Version: www-1.0

>Number:         38006
>Category:       bin
>Synopsis:       tcsh calls malloc() from signal handler without serialization
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    mp
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun May 12 16:20:01 PDT 2002
>Closed-Date:    Sat Aug 10 11:20:49 PDT 2002
>Last-Modified:  Sat Aug 10 11:20:49 PDT 2002
>Originator:     Marcel Moolenaar
>Release:        none :-)
>Organization:
>Environment:
FreeBSD dhcp01.pn.xcllnt.net 5.0-CURRENT FreeBSD 5.0-CURRENT #0: Sat May  4 15:29:52 PDT 2002 marcel@dhcp01.pn.xcllnt.net:/usr/obj/usr/src/sys/VAIO  i386

>Description:
At startup, for example when opening a GNOME terminal with tcsh as the
users shell, there's a possibility that a SIGWINCH is delivered while
tcsh is in free(). A SIGWINCH signal causes the display buffer to be
recreated (ReBufferDisplay()) and will call result in calls to free()
and malloc(). The following stacktrace demonstrates what happens:

(gdb) bt
#0  0x808e4a3 in access ()
#1  0x80ba9fa in abort () at /usr/src/lib/libc/../libc/stdlib/abort.c:78
#2  0x80b97a9 in wrtwarning (p=0x80ef54e "in free():") at /usr/src/lib/libc/../libc/stdlib/malloc.c:314
#3  0x80b97c8 in wrtwarning (p=0x80ef54e "in free():") at /usr/src/lib/libc/../libc/stdlib/malloc.c:315
#4  0x80ba5aa in malloc (size=1644) at /usr/src/lib/libc/../libc/stdlib/malloc.c:1093
#5  0x8079163 in smalloc (n=1644) at /usr/src/bin/csh/../../contrib/tcsh/tc.alloc.c:505
#6  0x80757d8 in ReBufferDisplay () at /usr/src/bin/csh/../../contrib/tcsh/ed.screen.c:506
#7  0x8077cf9 in ChangeSize (lins=24, cols=80) at /usr/src/bin/csh/../../contrib/tcsh/ed.screen.c:1742
#8  0x8071542 in check_window_size (force=0) at /usr/src/bin/csh/../../contrib/tcsh/ed.init.c:128
#9  0x8071564 in window_change (snum=28) at /usr/src/bin/csh/../../contrib/tcsh/ed.init.c:148
#10 <signal handler called>
#11 0x80baa8f in memcpy ()
#12 0x80ba6c9 in free (ptr=0x814f600) at /usr/src/lib/libc/../libc/stdlib/malloc.c:1125
#13 0x8079287 in sfree (p=0x814f600) at /usr/src/bin/csh/../../contrib/tcsh/tc.alloc.c:586
#14 0x805c2ca in blkfree (av0=0x814f600) at /usr/src/bin/csh/../../contrib/tcsh/sh.misc.c:169
#15 0x8057600 in backeval (cp=0x8150900, literal=0) at /usr/src/bin/csh/../../contrib/tcsh/sh.glob.c:842
#16 0x80574e8 in dobackp (cp=0x8147060, literal=0) at /usr/src/bin/csh/../../contrib/tcsh/sh.glob.c:784
#17 0x8056aa1 in globexpand (v=0x814ac54) at /usr/src/bin/csh/../../contrib/tcsh/sh.glob.c:386
#18 0x8057171 in globall (v=0x814ac50) at /usr/src/bin/csh/../../contrib/tcsh/sh.glob.c:632
#19 0x80622c1 in set1 (var=0x814acf0, vec=0x814ac50, head=0x8130fc4, flags=2) at /usr/src/bin/csh/../../contrib/tcsh/sh.set.c:616
#20 0x806227a in set (var=0x814acf0, val=0x8147060, flags=2) at /usr/src/bin/csh/../../contrib/tcsh/sh.set.c:601
#21 0x8061a41 in doset (v=0x814f200, c=0x814cce0) at /usr/src/bin/csh/../../contrib/tcsh/sh.set.c:292
#22 0x8053428 in func (t=0x814cce0, bp=0x80f4a44) at /usr/src/bin/csh/../../contrib/tcsh/sh.func.c:149
#23 0x80608d7 in execute (t=0x814cce0, wanttty=634, pipein=0x0, pipeout=0x0) at /usr/src/bin/csh/../../contrib/tcsh/sh.sem.c:657
#24 0x8060b15 in execute (t=0x814ccc0, wanttty=634, pipein=0x0, pipeout=0x0) at /usr/src/bin/csh/../../contrib/tcsh/sh.sem.c:734
#25 0x804a847 in process (catch=0) at /usr/src/bin/csh/../../contrib/tcsh/sh.c:2125
#26 0x804a0f9 in srcunit (unit=3, onlyown=1, hflg=0, av=0x0) at /usr/src/bin/csh/../../contrib/tcsh/sh.c:1661
#27 0x8049cce in srcfile (f=0x814b700 "USER", onlyown=1, flag=0, av=0x0) at /usr/src/bin/csh/../../contrib/tcsh/sh.c:1468
#28 0x8049c70 in srccat (cp=0x814ca00, dp=0x80f64a4) at /usr/src/bin/csh/../../contrib/tcsh/sh.c:1441
#29 0x8049973 in main (argc=0, argv=0xbfbffaa4) at /usr/src/bin/csh/../../contrib/tcsh/sh.c:1301

malloc() and free() are not reentrant and thus should be protected
from this situation.

>How-To-Repeat:
One approach would be to hack free() in libc to do a
kill(getpid(), SIGWINCH). The following patch has been verified
to simulate the condition (probably white-space corrupted):

Index: malloc.c
===================================================================
RCS file: /home/ncvs/src/lib/libc/stdlib/malloc.c,v
retrieving revision 1.68
diff -u -r1.68 malloc.c
--- malloc.c	24 Apr 2002 16:49:36 -0000	1.68
+++ malloc.c	12 May 2002 23:12:35 -0000
@@ -1120,8 +1120,10 @@
         THREAD_UNLOCK();
 	return;
     }
-    if (ptr != ZEROSIZEPTR)
-	    ifree(ptr);
+    if (ptr != ZEROSIZEPTR) {
+	kill(getpid(), 28);
+	ifree(ptr);
+    }
     UTRACE(ptr, 0, 0);
     malloc_active--;
     THREAD_UNLOCK();

>Fix:
Suggested fixes:
o  Don't malloc from a signal handler,
o  Block SIGWINCH in sfree().

>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->mp 
Responsible-Changed-By: marcel 
Responsible-Changed-When: Sun May 12 16:21:10 PDT 2002 
Responsible-Changed-Why:  
Over to maintainer of tcsh. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=38006 
State-Changed-From-To: open->closed 
State-Changed-By: mp 
State-Changed-When: Sat Aug 10 11:20:35 PDT 2002 
State-Changed-Why:  
Fixed in tcsh-6.12.00. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=38006 
>Unformatted:
