|
In x86 and x86_64 it doesn't matter whether the caller has control or not over the return address, because there's a change of privilege when the kernel returns from the interrupt (IRET instruction). So at that point it would be equivalent for the userspace app to just jump to whatever address it wants. The caller does not have control over the return address. When int n or syscall instructions are executed, it's the processor who pushes the current context onto the kernel stack (pointed by ss0:esp0), so when you run iret, everything will go back to normal. Even if the caller had control over this return address, the CR3 does not change [without taking KPTI into consideration], so the memory mappings will still be the same, and everything would be handled with paging enabled, so there's no "arbitrary physical address". You would only be allowed to jump to anything that you have already mapped, and given that there's a privilege change, you would only be able to access userspace memory. This has nothing to do with whether the syscall parameters are passed down the stack or not. In x86 and x86_64, when you make a syscall and the kernel handles it, the stacks change, so if you were to pass parameters via the stack, you would need to be able to access the userspace stack from the kernel and it sounds like a mess (but possible). The registers, on the other hand, are available for the syscall handler to use, so it's easier to just set the parameters there. |