Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Thu, 18 Apr 2024 15:07:38 -0700
From: Alan Coopersmith <alan.coopersmith@...cle.com>
To: libc-coord@...ts.openwall.com
Subject: Re: Preventing re-use of jmp_buf?

On 4/18/24 10:25, Paul Eggert wrote:
> On 2024-04-18 03:36, Florian Weimer wrote:
>>   think it's possible to meet all the preconditions for longjmp and call
>> it multiple times after a setjmp call, on the same buffer.  Therefore, I
>> don't think this would be a conforming or just compatible change.
> 
> Quite right.
> 
> However, couldn't we catch many instances of the more-important case where 
> longjmp called with a jmp_buf that's no longer valid? Something involving a 
> per-thread nonce that's tweaked each time setjmp is called, and where the 
> nonce's value is stored in both the jmp_buf and in the setjmp caller's frame, so 
> that longjmp could reliably crash if the nonce is corrupted. We could do this if 
> fortification is enabled.

Right - the case that originated this conversation was:
https://gitlab.freedesktop.org/xorg/lib/libxmu/-/issues/2

In the test code, I had written test cases to make sure that the functions
in question correctly detected and reported errors.  But since the error
handlers in question exit the program, after calling a specified error
handling/cleanup callback, I used setjmp() and longjmp() to jump from
the callback back to the test code.

The problem was there were multiple test functions, and I had called
setjmp() in the first, but not the second, and the jump buffer was
invalid after the first exited, but the longjmp() was still called
from the second one, which crashed with a garbage stack.

Ideally I'd be able to call something to clear the jump buffer before
exiting each function, so any further calls to longjmp() without a new
setjmp() can abort with the right stack, not stack garbage - but I can't
find any sort of "clearjmp()" function to do that.  I assume I can do
something like "memset(env, 0, sizeof(jmp_buf))" but that seems to rely
on implementation details and risks memory leaks if an implementation
sticks pointers to allocated memory in there.  I'd prefer a cleaner
documented solution, but haven't found one.

-- 
         -Alan Coopersmith-                 alan.coopersmith@...cle.com
          Oracle Solaris Engineering - https://blogs.oracle.com/solaris

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.