[CRIU] [PATCH 1/4] pie/x86_64: syscall clobbers rcx and r11
Cyrill Gorcunov
gorcunov at gmail.com
Tue Jun 16 05:32:12 PDT 2015
On Mon, Jun 15, 2015 at 03:50:34PM -0600, Tycho Andersen wrote:
> o_O this is one of those "how has nobody ever hit this" bugs.
>
> According to:
>
> http://stackoverflow.com/questions/2535989/what-are-the-calling-conventions-for-unix-linux-system-calls-on-x86-64
>
> syscall on x86_64 clobbers rcx and r11. We should mark these registers as
> clobbered in RUN_CLONE_RESTORE_FN so that gcc avoids using them, e.g.:
>
> ...<__export_restore_task>
> ...
> 1894: 49 89 db mov r11,rbx
> 1897: 4c 8d 4c 24 60 lea r9,[rsp+0x60]
> 189c: 48 89 eb mov rbx,rbp
> 189f: 48 89 44 24 10 mov QWORD PTR [rsp+0x10],rax
> 18a4: 48 8d 44 24 30 lea rax,[rsp+0x30]
> 18a9: 48 89 44 24 18 mov QWORD PTR [rsp+0x18],rax
> 18ae: eb 53 jmp 1903 <clone_end+0x15>
>
> 00000000000018b0 <clone_emul>:
> 18b0: 48 8b 74 24 08 mov rsi,QWORD PTR [rsp+0x8]
> 18b5: 48 83 ee 10 sub rsi,0x10
> 18b9: 48 89 ef mov rdi,rbp
> 18bc: 48 89 7e 08 mov QWORD PTR [rsi+0x8],rdi
> 18c0: 49 8b 7b 20 mov rdi,QWORD PTR [r11+0x20]
> 18c4: 48 89 3e mov QWORD PTR [rsi],rdi
> 18c7: 48 c7 c7 00 0d 05 00 mov rdi,0x50d00
> 18ce: 48 8b 54 24 18 mov rdx,QWORD PTR [rsp+0x18]
> 18d3: 4d 89 fa mov r10,r15
> 18d6: b8 38 00 00 00 mov eax,0x38
> 18db: 0f 05 syscall
> 18dd: 48 85 c0 test rax,rax
> 18e0: 74 05 je 18e7 <thread_run>
> 18e2: 48 89 c5 mov rbp,rax
> 18e5: eb 07 jmp 18ee <clone_end>
>
> 00000000000018e7 <thread_run>:
> 18e7: 48 31 ed xor rbp,rbp
> 18ea: 58 pop rax
> 18eb: 5f pop rdi
> 18ec: ff d0 call rax
>
> 00000000000018ee <clone_end>:
> 18ee: 41 83 c5 01 add r13d,0x1
> 18f2: 49 81 c7 00 8c 00 00 add r15,0x8c00
> 18f9: 45 39 6b 14 cmp DWORD PTR [r11+0x14],r13d
>
> will cause a seg fault because r11 is clobbered.
have you actually got sygsev here ever? this is a clone
emulation which makes the kernel to allocate new registers
set, iow once syscall is complete there will be two tasks
one with former r11 and one with copy, the caller access
unmodified/former r11 (upon syscall enter the kernel
saves former pt-regs). same time strictly speaking
r11 is a temp register which is not callee saved
so to be on safe side lets stick with your patch
(rcx clobbering is useless here but let it be).
More information about the CRIU
mailing list