From: Sergiu Moga Date: Mon, 24 Mar 2025 16:46:16 +0000 (+0200) Subject: lib/syscall_shim/arch/x86_64: Restore `RIP` from the auxiliary stack X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=06f9907e2d8597665167f016d27b6015e7dc53e2;p=unikraft%2Funikraft.git lib/syscall_shim/arch/x86_64: Restore `RIP` from the auxiliary stack Before this patch, we would simply rely on the original pushed RIP following the call instruction that got to our assembly wrapper. However this may not be the same in cases such as those of the clone or vfork system calls if the child were to reuse the stack: the child could pop the return address before the parent gets the chance to do it and even call some other functions (like execve), overwriting whatever previously was at the bottom of the stack that the parent had prior to invoking the system call. To solve this, simply use the RIP pushed at the beginning of the wrapper instead of assuming the bottom of the stack is untouched. Signed-off-by: Sergiu Moga Approved-by: Michalis Pappas Reviewed-by: Michalis Pappas Reviewed-by: Andrei Tatar GitHub-Closes: #1618 --- diff --git a/lib/syscall_shim/arch/x86_64/include/arch/syscall_prologue.h b/lib/syscall_shim/arch/x86_64/include/arch/syscall_prologue.h index 53e90da76..a2dbb7101 100644 --- a/lib/syscall_shim/arch/x86_64/include/arch/syscall_prologue.h +++ b/lib/syscall_shim/arch/x86_64/include/arch/syscall_prologue.h @@ -121,13 +121,32 @@ "popq %r13\n\t" \ "popq %r12\n\t" \ "popq %rbp\n\t" \ - "popq %rbx\n\t" \ - "/* Restore rsp from where it was stored */\n\t" \ - "movq 104(%rsp), %rsp\n\t" \ + "/* Now when we pop we get the old rbx but we hold\n\t" \ + " * onto it for a little while so that we can do\n\t" \ + " * what we do below.\n\t" \ + " */\n\t" \ + "/* Restore rsp from where it was stored, but put\n\t" \ + " * it for now in the r11 scratch register so that\n\t" \ + " * we can still have access to the auxstack\n\t" \ + " */\n\t" \ + "movq 112(%rsp), %r11\n\t" \ + "/* Put in rbx the rip we are supposed to return\n\t" \ + " * to.\n\t" \ + " */\n\t" \ + "movq 88(%rsp), %rbx\n\t" \ + "/* Exchange stacks: after this we will have in\n\t" \ + " * r11 the auxstack and in rsp the stack our\n\t" \ + " * caller had.\n\t" \ + " */\n\t" \ + "xchgq %r11, %rsp\n\t" \ "/* Adjust saved stack to original value; ret\n\t" \ " * expects return address on top of stack\n\t" \ " */\n\t" \ - "subq $8, %rsp\n\t" \ + "pushq %rbx\n\t" \ + "/* Lastly, restore the callee-saved rbx we did not\n\t"\ + " * previously pop together with the others.\n\t" \ + " */\n\t" \ + "movq (%r11), %rbx\n\t" \ "ret\n\t" \ );