aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2015-04-07 06:40:34 +0100
committerMichael Brown <mcb30@ipxe.org>2015-04-07 06:40:34 +0100
commit00ff3d8bb3af0831ced99e8b6f226291ca236883 (patch)
tree1c65ea27c4a641eb229386365ecffd7210d0fba7
parentf557794ab3ccae444653a25b889cc51d10e6f0c3 (diff)
downloadipxe-00ff3d8bb3af0831ced99e8b6f226291ca236883.tar.gz
[libc] Fix typo in longjmp()
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>
-rw-r--r--src/arch/i386/core/setjmp.S6
1 files changed, 3 insertions, 3 deletions
diff --git a/src/arch/i386/core/setjmp.S b/src/arch/i386/core/setjmp.S
index 68277b99..81d3b491 100644
--- a/src/arch/i386/core/setjmp.S
+++ b/src/arch/i386/core/setjmp.S
@@ -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 */