thehajime / linux

Linux kernel source tree
https://lkl.github.io/
Other
3 stars 1 forks source link

rt_sigframe mistery... #3

Closed thehajime closed 1 week ago

thehajime commented 1 week ago

why sigreturn substract sp-sizeof(long) ?

thehajime commented 1 week ago
diff --git a/arch/x86/um/signal.c b/arch/x86/um/signal.c
index 27a5b4b022ac..08161041d0e9 100644
--- a/arch/x86/um/signal.c
+++ b/arch/x86/um/signal.c
@@ -538,7 +538,9 @@ int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
                return err;

 #ifndef CONFIG_MMU
-       /* XXX: need to push handler address at SP */
+       /* we need to push handler address at top of stack, as
+        * __kernel_vsyscall, called after this returns with ret with
+        * stack contents, thus push the handler here. */
        frame = (struct rt_sigframe __user *) ((unsigned long) frame -
                                               sizeof(unsigned long));
        err |= __put_user((unsigned long)ksig->ka.sa.sa_handler,
@@ -571,7 +573,17 @@ SYSCALL_DEFINE0(rt_sigreturn)
        struct rt_sigframe __user *frame =
                (struct rt_sigframe __user *)(sp - sizeof(long));
 #ifndef CONFIG_MMU
-       /* XXX: need to pop handler address at SP */
+       /**
+        * we enter here with: 
+        *
+        * __restore_rt:
+        *     mov $15, %rax
+        *     call *%rax (translated from syscall)
+        *
+        * (code is from musl libc)
+        * so, stack needs to be popped of "call"ed address before
+        * looking at rt_sigframe.
+        */
        frame = (struct rt_sigframe __user *)((unsigned long)frame + sizeof(long));
 #endif
        struct ucontext __user *uc = &frame->uc;
thehajime commented 1 week ago

https://github.com/thehajime/linux/blob/0d60af3d109d7e0854aa9f139c2bda51ff4362ee/arch/x86/um/signal.c#L540-L548 https://github.com/thehajime/linux/blob/0d60af3d109d7e0854aa9f139c2bda51ff4362ee/arch/x86/um/signal.c#L575-L588