Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 22 Oct 1997 13:59:25 -0700 (PDT)
From:      tadhunt@bell-labs.com
To:        freebsd-gnats-submit@FreeBSD.ORG
Subject:   i386/4826: libc_r, buggy setjmp implementation (rookie error)
Message-ID:  <199710222059.NAA27302@hub.freebsd.org>
Resent-Message-ID: <199710222100.OAA27386@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         4826
>Category:       i386
>Synopsis:       libc_r, buggy setjmp implementation (rookie error)
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Oct 22 14:00:01 PDT 1997
>Last-Modified:
>Originator:     Tad Hunt
>Organization:
Lucent Technologies, Bell Labs
>Release:        2.2.5-971018-BETA
>Environment:
doesn't matter.  It's not specific to a particular version of FreeBSD,
it's incorrect implementation of a library...

>Description:
 
    I was looking at the libc_r implementation of setjmp
(lib/libc_r/uthread/uthread_setjmp.c) from (FreeBSD-2.2.5-101897)

from lib/libc_r/uthread/uthread_setjmp.c:
int
setjmp(jmp_buf env)
{
	return (_thread_sys_setjmp(env));
}

where _thread_sys_setjmp is implemented in lib/libc/i386/gen/setjmp.S
as something like the following:

#ifdef _THREAD_SAFE
ENTRY(_thread_sys_setjmp)
#else
        ENTRY(setjmp)
        #endif
        [... essentially the same implementation for both cases, except
         for some signal stuff]
 
In the case of threaded programs calling setjmp() (instead of calling
_thread_sys_setjmp()) the wrong environment gets saved in the jmp_buf.
When longjmp does it's work, it returns into setjmp() (instead of returning
into the caller of setjmp().  Essentially the following is happening:
 
        jmp_buf foo;
        main()
        {
            bar();
            longjmp(foo, 1);
        }
 
        bar()
        {
            setjmp(foo);
        }
 
-Tad
 

>How-To-Repeat:

% gcc -static foo.c -lc_r
% ./a.out
Memory Fault (core dumped)
%

foo.c:

#include <pthread.h>
#include <setjmp.h>

jmp_buf j;

void
main(void)
{
	if(setjmp(j)) {
		printf("setjmp returned the second time\n");
		exit(1);
	}
	longjmp(j, 69);
}
>Fix:
diff lib/libc/i386/gen/setjmp.orig.S lib/libc/i386/gen/setjmp.S
59,30d58
< #else
< ENTRY(setjmp)
61a60
> ENTRY(setjmp)
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199710222059.NAA27302>