Outside sandbox the printf function address is 0x4026,b0b0
;
Inside sandbox the printf function address is 0x401d,6ec0,0000,0000
, which invalid address.
The problem comes out to be an issue of the calling convention. By default, functions are called by instruction jalr $t9
, where t9
stores the entry address for the target function.
When the target function is executed, the compiler still uses t9
to compute the address of variables and global functions, such as printf
.
Possible solutions:
0x20b58 <test_sandboxA+160>: nop
0x20b5c: nop
=> 0x20b60 <main>: daddiu sp,sp,-144 // t9: 0x20b60; sp = 0x7f,fffe,fa50 - 144 = 0x7f,fffe,f9c0
0x20b64 <main+4>: sd ra,136(sp) // ra: 0x2010c
0x20b68 <main+8>: sd s8,128(sp) // s8: 0x7ffffefa50
0x20b6c <main+12>: sd gp,120(sp) // gp: 0x48010
0x20b70 <main+16>: move s8,sp // s8 = 0x7f,fffe,f9c0
0x20b74 <main+20>: lui at,0x2 // at = 0x2,0000
0x20b78 <main+24>: daddu at,at,t9 // t9: 0x2,0b60; at = 0x40b60;
0x20b7c <main+28>: daddiu at,at,29872 // at = 0x48010
0x20b80 <main+32>: sw zero,116(s8) // [0x7ffffefa34] = 0
0x20b84 <main+36>: ld v0,-32688(at) // v0 = [0x48010 - 32688] = [0x40060] = 0x1,0000
0x20b88 <main+40>: daddiu a0,v0,2083 // a0 = 0x1,0000 + 2083 = 0x10823
0x20b8c <main+44>: ld t9,-32424(at) // t9 = [0x48010 - 32424] = [0x40168] = 0x4026,b0b0
0x20b90 <main+48>: move gp,at // gp = 0x48010
0x20b94 <main+52>: sd at,104(s8) // [stacktop] = 0x48010
0x20b98 <main+56>: jalr t9 // t9: 0x4026b0b0
0x20b9c <main+60>: nop
With Wrong t9
, which is not changed since updated when calling sandbox_invoke
using jalr $t9
; when function sandboxA_print
is called via ccall
and executed, compiler still generate code assuming t9
points to the function entry.
0x20444 <sandbox_invoke>: ccall $c1,$c2,1 // t9: 0x20444; at: 0x48010
0x20448 <sandbox_invoke+4>: nop
0x2044c <sandbox_invoke_end>: 0x4170001
0x20450 <sandboxA_print>: daddiu sp,sp,-32 // sp: 0x7f,fffe,f9a0; t9: 0x20444; at: 0x48010;
0x20454 <sandboxA_print+4>: sd ra,24(sp) // sp: 0x7f,fffe,f980; ra: 0x20b48;
0x20458 <sandboxA_print+8>: sd s8,16(sp) // s8: 0x7f,fffe,f9a0;
0x2045c <sandboxA_print+12>: sd gp,8(sp) // gp: 0x48010;
0x20460 <sandboxA_print+16>: move s8,sp // s8 = 0x7f,fffe,f980;
0x20464 <sandboxA_print+20>: lui at,0x2 // at = 0x2,0000
0x20468 <sandboxA_print+24>: daddu at,at,t9 // at += 0x2,0444 = 0x4,0444
0x2046c <sandboxA_print+28>: daddiu at,at,31680 // at = 0x48004
0x20470 <sandboxA_print+32>: ld v0,-32688(at) // v0 = [0x40054] = 0x3,0000,0000,0000
0x20474 <sandboxA_print+36>: daddiu a0,v0,2257 // a0 = 0x3,0000,0000,08d1
0x20478 <sandboxA_print+40>: ld t9,-32424(at) // t9 = [0x48004 - 32424] = [0x4015c] = 0x401d,6ec0,0000,0000
0x2047c <sandboxA_print+44>: move gp,at // gp = 0x48004
0x20480 <sandboxA_print+48>: jalr t9 // t9: this is supposed to be printf. but the address is 0x401d,6ec0,0000,0000, invalid.
0x20484 <sandboxA_print+52>: nop
gdb commands:
set mips abi cheri128
b main, sandboxA_print, test_sandboxA
x /30gi ($pc-0x10) x /20gx ($at - 32688)
info reg v0
si 30 ni 20
If you could revise
the fundmental principles of
computer system design
to improve security...
... what would you change?