Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- == Simple setjmp/longjmp program ==
- static jmp_buf jbuf;
- static void sighandler(int signo)
- {
- siglongjmp(jbuf, signo);
- }
- static void setup_sighandler(void)
- {
- signal(SIGINT, sighandler);
- if (0 == sigsetjmp(jbuf, 0)) {
- return;
- }
- exit(42);
- }
- int main(int argc, char *argv[])
- {
- setup_sighandler();
- pause();
- return 0;
- }
- objdump -saD -j .text test-setjmp:
- 004006c0 <sighandler>:
- 4006c0: 27bdffe0 addiu sp,sp,-32
- 4006c4: afbf001c sw ra,28(sp)
- 4006c8: afbe0018 sw s8,24(sp)
- 4006cc: 03a0f021 move s8,sp
- 4006d0: 3c1c0042 lui gp,0x42
- 4006d4: 279c8a50 addiu gp,gp,-30128
- 4006d8: afbc0010 sw gp,16(sp)
- 4006dc: afc40020 sw a0,32(s8)
- 4006e0: 3c020041 lui v0,0x41
- 4006e4: 24440ac0 addiu a0,v0,2752
- 4006e8: 8fc50020 lw a1,32(s8)
- 4006ec: 8f82803c lw v0,-32708(gp)
- 4006f0: 0040c821 move t9,v0
- 4006f4: 0320f809 jalr t9
- 4006f8: 00000000 nop
- 004006fc <setup_sighandler>:
- 4006fc: 27bdffe0 addiu sp,sp,-32 => setup new stack frame
- 400700: afbf001c sw ra,28(sp) => save return address to main
- 400704: afbe0018 sw s8,24(sp) => save main's frame pointer
- 400708: 03a0f021 move s8,sp => adjust frame pointer
- 40070c: 3c1c0042 lui gp,0x42
- 400710: 279c8a50 addiu gp,gp,-30128
- 400714: afbc0010 sw gp,16(sp) => save gp
- 400718: 24040002 li a0,2
- 40071c: 3c020040 lui v0,0x40
- 400720: 244506c0 addiu a1,v0,1728
- 400724: 8f828054 lw v0,-32684(gp)
- 400728: 0040c821 move t9,v0
- 40072c: 0320f809 jalr t9 => signal()
- 400730: 00000000 nop
- 400734: 8fdc0010 lw gp,16(s8) => restore gp
- 400738: 3c020041 lui v0,0x41
- 40073c: 24440ac0 addiu a0,v0,2752
- 400740: 00002821 move a1,zero
- 400744: 8f828044 lw v0,-32700(gp)
- 400748: 0040c821 move t9,v0
- 40074c: 0320f809 jalr t9 => sigsetjmp()
- 400750: 00000000 nop
- 400754: 8fdc0010 lw gp,16(s8) => Next instruction after sigsetjmp(): restore gp
- 400758: 10400006 beqz v0,400774 <setup_sighandler+0x78>
- 40075c: 00000000 nop
- 400760: 2404002a li a0,42 => sigsetjmp() != 0 (siglongjmp was called)
- 400764: 8f82804c lw v0,-32692(gp)
- 400768: 0040c821 move t9,v0
- 40076c: 0320f809 jalr t9 => exit
- 400770: 00000000 nop
- 400774: 00000000 nop => sigsetjmp() == 0
- 400778: 03c0e821 move sp,s8
- 40077c: 8fbf001c lw ra,28(sp) => restore return address
- 400780: 8fbe0018 lw s8,24(sp) => restore frame pointer
- 400784: 27bd0020 addiu sp,sp,32
- 400788: 03e00008 jr ra => return
- 40078c: 00000000 nop
- 1. In setup_sighandler() before sigsetjmp()
- (gdb) p /x $gp
- $1 = 0x418a50
- (gdb) p /x $s8
- $2 = 0x7fff6a58
- (gdb) x /20x $s8
- 0x7fff6a58: 0x77fc5e00 0x00400834 0x77fd4544 0x00400590
- 0x7fff6a68: 0x00418a50 0x77e60c94 0x7fff6a78 0x004007bc
- 0x7fff6a78: 0x77fc5e00 0x00000000 0x00400590 0x00000000
- 0x7fff6a88: 0x00418a50 0x77ff6fac 0x004e9e7c 0x77e3f378
- 0x7fff6a98: 0x00000001 0x7fff6b74 0x77fc5e00 0x00000000
- gp is set at offset 16 from frame pointer.
- 2. In setup_sighandler() after sigsetjmp()
- Execution resumes at:
- lw gp,16(s8)
- After this instruction, gp and s8 are correct (same output as in 1.)
- 3. In sighandler() before siglongjmp()
- Let's see what setup_sighandler's stack frame now looks like:
- (gdb) x /20x 0x7fff6a58
- 0x7fff6a58: 0x77fc5e00 0x00400834 0x00410ac0 0x00000000
- 0x7fff6a68: 0x7fff6a58 0x7fff6a58 0x77fff000 0x004007d0
- 0x7fff6a78: 0x77fc5e00 0x00000000 0x00400590 0x00000000
- 0x7fff6a88: 0x00418a50 0x77ff6fac 0x004e9e7c 0x77e3f378
- 0x7fff6a98: 0x00000001 0x7fff6b74 0x77fc5e00 0x00000000
- At least the offset where gp used to be stored has been smashed.
- 4. In setup_sighandler after siglongjmp()
- Execution resumes at:
- lw gp,16(s8)
- (gdb) p /x $s8
- $6 = 0x7fff6a58
- s8 was correctly restored.
- (gdb) x /20x $s8
- 0x7fff6a58: 0x77fc5e00 0x00400834 0x00410ac0 0x00000000
- 0x7fff6a68: 0x7fff6a58 0x7fff6a58 0x77fff000 0x004007d0
- 0x7fff6a78: 0x77fc5e00 0x00000000 0x00400590 0x00000000
- 0x7fff6a88: 0x00418a50 0x77ff6fac 0x004e9e7c 0x77e3f378
- 0x7fff6a98: 0x00000001 0x7fff6b74 0x77fc5e00 0x00000000
- At we expected from 3. the setup_sighandler's frame pointer contains random values, especially at the offset where gp is supposed to be stored.
- So the instruction lw gp,16(s8) will not restore gp properly.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement