]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[libc] Fix typo in longjmp()
authorMichael Brown <mcb30@ipxe.org>
Tue, 7 Apr 2015 05:40:34 +0000 (06:40 +0100)
committerMichael Brown <mcb30@ipxe.org>
Tue, 7 Apr 2015 05:40:34 +0000 (06:40 +0100)
Commit 8ab4b00 ("[libc] Rewrite setjmp() and longjmp()") introduced a
regression in which the saved values of %ebx, %esi, and %edi were all
accidentally restored into %esp.  The result is that the second and
subsequent returns from setjmp() would effectively corrupt %ebx, %esi,
%edi, and the stack pointer %esp.

Use of setjmp() and longjmp() is generally discouraged: our only use
occurs as part of the implementation of PXENV_RESTART_TFTP, since the
PXE API effectively mandates its use here.  The call to setjmp()
occurs at the start of pxe_start_nbp(), where there are almost
certainly no values held in %ebx, %esi, or %edi.  The corruption of
these registers therefore had no visible effect on program execution.
The corruption of %esp would have been visible on return from
pxe_start_nbp(), but there are no known PXE NBPs which first call
PXENV_RESTART_TFTP and subsequently attempt to return to the PXE base
code.  The effect on program execution was therefore similar to that
of moving the stack to a pseudo-random location in the 32-bit address
space; this will often allow execution to complete successfully since
there is a high chance that the pseudo-random location will be unused.
The regression therefore went undetected for around one month.

Fix by restoring the correct registers from the saved jmp_buf
structure.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/arch/i386/core/setjmp.S

index 68277b990d590ee1ff18268e6c4b94cdd54ea7ee..81d3b491153884a0171a0447c856dd98192973ef 100644 (file)
@@ -52,9 +52,9 @@ longjmp:
 1:     /* Restore stack pointer */
        movl    env_stack(%edx), %esp
        /* Restore other registers */
-       movl    env_ebx(%edx), %esp
-       movl    env_esi(%edx), %esp
-       movl    env_edi(%edx), %esp
+       movl    env_ebx(%edx), %ebx
+       movl    env_esi(%edx), %esi
+       movl    env_edi(%edx), %edi
        movl    env_ebp(%edx), %ebp
        /* Replace return address on the new stack */
        popl    %ecx    /* discard */