0
votes

I have implemented a syscall on x86_64 Linux 3.0, and would like to know how to get the calling process's stack pointer (%rsp). My syscall is a plain vanilla syscall...

I'm used to using task_pt_regs to get the stack frame of the calling process, but from arxh/x86/include/asm/ptrace.h, comments in struct pt_regs note that non-tracing syscalls don't read all registers: ip, cs, flags, sp and ss are not set when the CPU syscall instruction is invoked and my actual syscall being called. In other words, in my syscall task_pt_regs(current)->ss is garbage.

For calls like sys_fork, a special macro in arch/x86/kernel/entry_64.S (PTREGSCALL) sets up the sys_fork function to be called with a proper pt_regs stack frame.

How can I extract values like IP and SS in my syscall without forcing an extra argument onto my custom system call like sys_fork with PTREGSCALL?

1

1 Answers

0
votes

If can understand well when a syscall is invoked the CPU jumps to the kernel code (jump of privileged), in that moment the CPU fills the stack with the CS, RIP, RSP and Eflags registers in order to return to user code when the handler executes an IRET (Return from Interruption).

This means that you may find the RSP and RIP of the calling process just looking in the stack when the syscall is executed.

You may get more information in the "AMD64 Architecture, Programmer’s Manual, Volume 2: System Programming", page 292. It's called "Long-Mode Stack After Interrupt—Higher Privilege".

In the previous answer, I've ignored a few stuff around the way that Linux kernel handles the syscalls but it doesn't change the answer.