So I've been trying to implement signals for a week now, and for the last 5 days I've been very confused about why my code doesn't work.
The signal handling part does seem to work (for non RT signals at least) and the signal handler wrapper is correctly called.
What is confusing is that after the signal return syscall, the next context switch will result in a GPF with a nonsense (0xedc0) segment selector on the iretq instruction.
Here is my context push/pop code:
Code: Select all
void task_setup_stack(thread_t* task, uint64_t entry_point)
{
task_context_stack_push(task, task->rsp);
LOG(DEBUG, "Pushed context:");
log_context(task);
// if (task->context_sp >= TASK_KERNEL_STACK_BOTTOM_ADDRESS + 16) return;
task_stack_push(task, (task->ring == 0) ? KERNEL_DATA_SEGMENT : USER_DATA_SEGMENT);
task_stack_push(task, task->rsp + 8);
task_stack_push(task, 0x202); // get_rflags()
task_stack_push(task, (task->ring == 0) ? KERNEL_CODE_SEGMENT : USER_CODE_SEGMENT);
task_stack_push(task, entry_point);
task_stack_push(task, (uint64_t)iretq_instruction);
task_stack_push(task, (uint64_t)unlock_scheduler);
task_stack_push(task, (uint64_t)cleanup_tasks);
task_stack_push(task, (uint64_t)end_context_switch);
task_stack_push(task, 0); // rax
task_stack_push(task, 0); // rbx
task_stack_push(task, 0); // rcx
task_stack_push(task, (task->ring == 0) ? KERNEL_DATA_SEGMENT : USER_DATA_SEGMENT); // rdx
task_stack_push(task, 0); // r8
task_stack_push(task, 0); // r9
task_stack_push(task, 0); // r10
task_stack_push(task, 0); // r11
task_stack_push(task, 0); // r12
task_stack_push(task, 0); // r13
task_stack_push(task, 0); // r14
task_stack_push(task, 0); // r15
task_stack_push(task, 0); // rbp
}
void task_unsetup_stack(thread_t* task)
{
task->rsp = task_context_stack_pop(task);
LOG(DEBUG, "Popped context:");
log_context(task);
}
void task_context_stack_push(thread_t* task, uint64_t rsp)
{
LOG(TRACE, "task_context_stack_push(%p, %#" PRIx64 ")", task, rsp);
task_write_at_address_8b(task, task->context_sp, rsp);
task->context_sp += 8;
}
uint64_t task_context_stack_pop(thread_t* task)
{
task->context_sp -= 8;
uint64_t ret = task_read_at_address_8b(task, task->context_sp);
LOG(TRACE, "task_context_stack_pop(%p) = %#" PRIx64 " (%#" PRIx64 ")", task, ret, task->rsp);
return ret;
}Here are the logs:
Code: Select all
2026-02-21 12:55:03.058 - [Debug] Sending signal 2 to pgrp 1
2026-02-21 12:55:03.058 - [Debug] pid 1 receiving signal 2
2026-02-21 12:55:03.058 - [Debug] Signal was sent to the process
2026-02-21 12:55:03.059 - [Trace] task_context_stack_push(0xffff8000029ec020, 0x7fffffbfeb98)
2026-02-21 12:55:03.059 - [Debug] Pushed context:
2026-02-21 12:55:03.059 - [Debug] log_context (rsp = 0x00007fffffbfeb98)
2026-02-21 12:55:03.059 - [Debug] 0x00007fffffbfeb98 (rsp + 0) = 0x00007fffffbfec18
2026-02-21 12:55:03.059 - [Debug] 0x00007fffffbfeba0 (rsp + 1) = 0x0000000000000400
2026-02-21 12:55:03.059 - [Debug] 0x00007fffffbfeba8 (rsp + 2) = 0xffffffffffe37520
2026-02-21 12:55:03.059 - [Debug] 0x00007fffffbfebb0 (rsp + 3) = 0xffffffffffe373c4
2026-02-21 12:55:03.059 - [Debug] 0x00007fffffbfebb8 (rsp + 4) = 0xffffffffffe37410
2026-02-21 12:55:03.059 - [Debug] 0x00007fffffbfebc0 (rsp + 5) = 0xffffffffffe17510
2026-02-21 12:55:03.059 - [Debug] 0x00007fffffbfebc8 (rsp + 6) = 0x0000000000000130
2026-02-21 12:55:03.059 - [Debug] 0x00007fffffbfebd0 (rsp + 7) = 0xffff80000ffe0060
2026-02-21 12:55:03.059 - [Debug] 0x00007fffffbfebd8 (rsp + 8) = 0xffff8000029e5f50
2026-02-21 12:55:03.059 - [Debug] 0x00007fffffbfebe0 (rsp + 9) = 0x0000000000000010
2026-02-21 12:55:03.059 - [Debug] 0x00007fffffbfebe8 (rsp + 10) = 0x00000000ffffffff
2026-02-21 12:55:03.059 - [Debug] 0x00007fffffbfebf0 (rsp + 11) = 0xffff8000029ec020
2026-02-21 12:55:03.059 - [Debug] 0x00007fffffbfebf8 (rsp + 12) = 0x0000000000000207
2026-02-21 12:55:03.059 - [Debug] 0x00007fffffbfec00 (rsp + 13) = 0xffffffffffe0feff
2026-02-21 12:55:03.059 - [Debug] 0x00007fffffbfec08 (rsp + 14) = 0xffffffffffe373c4
2026-02-21 12:55:03.059 - [Debug] 0x00007fffffbfec10 (rsp + 15) = 0x0000000000000015
2026-02-21 12:55:03.059 - [Debug] 0x00007fffffbfec18 (rsp + 16) = 0x00007fffffbfec38
2026-02-21 12:55:03.059 - [Debug] 0x00007fffffbfec20 (rsp + 17) = 0xffffffffffe0b887
2026-02-21 12:55:03.059 - [Debug] 0x00007fffffbfec28 (rsp + 18) = 0x0000000000000246
2026-02-21 12:55:03.059 - [Debug] 0x00007fffffbfec30 (rsp + 19) = 0xffffffffffe373c4
2026-02-21 12:55:03.086 - [Trace] task_context_stack_pop(0xffff8000029ec020) = 0x7fffffbfeb98 (0x7fffffbfed40)
2026-02-21 12:55:03.086 - [Debug] Popped context:
2026-02-21 12:55:03.086 - [Debug] log_context (rsp = 0x00007fffffbfeb98)
2026-02-21 12:55:03.086 - [Debug] 0x00007fffffbfeb98 (rsp + 0) = 0x00007fffffbfec18
2026-02-21 12:55:03.086 - [Debug] 0x00007fffffbfeba0 (rsp + 1) = 0x0000000000000400
2026-02-21 12:55:03.086 - [Debug] 0x00007fffffbfeba8 (rsp + 2) = 0xffffffffffe37520
2026-02-21 12:55:03.086 - [Debug] 0x00007fffffbfebb0 (rsp + 3) = 0xffffffffffe373c4
2026-02-21 12:55:03.086 - [Debug] 0x00007fffffbfebb8 (rsp + 4) = 0xffffffffffe37410
2026-02-21 12:55:03.086 - [Debug] 0x00007fffffbfebc0 (rsp + 5) = 0xffffffffffe17510
2026-02-21 12:55:03.086 - [Debug] 0x00007fffffbfebc8 (rsp + 6) = 0x0000000000000130
2026-02-21 12:55:03.086 - [Debug] 0x00007fffffbfebd0 (rsp + 7) = 0xffff80000ffe0060
2026-02-21 12:55:03.086 - [Debug] 0x00007fffffbfebd8 (rsp + 8) = 0xffff8000029e5f50
2026-02-21 12:55:03.086 - [Debug] 0x00007fffffbfebe0 (rsp + 9) = 0x0000000000000010
2026-02-21 12:55:03.086 - [Debug] 0x00007fffffbfebe8 (rsp + 10) = 0x00000000ffffffff
2026-02-21 12:55:03.086 - [Debug] 0x00007fffffbfebf0 (rsp + 11) = 0xffff8000029ec020
2026-02-21 12:55:03.086 - [Debug] 0x00007fffffbfebf8 (rsp + 12) = 0x0000000000000207
2026-02-21 12:55:03.086 - [Debug] 0x00007fffffbfec00 (rsp + 13) = 0xffffffffffe0feff
2026-02-21 12:55:03.086 - [Debug] 0x00007fffffbfec08 (rsp + 14) = 0xffffffffffe373c4
2026-02-21 12:55:03.086 - [Debug] 0x00007fffffbfec10 (rsp + 15) = 0x0000000000000015
2026-02-21 12:55:03.086 - [Debug] 0x00007fffffbfec18 (rsp + 16) = 0x00007fffffbfec38
2026-02-21 12:55:03.086 - [Debug] 0x00007fffffbfec20 (rsp + 17) = 0xffffffffffe0b887
2026-02-21 12:55:03.086 - [Debug] 0x00007fffffbfec28 (rsp + 18) = 0x0000000000000246
2026-02-21 12:55:03.086 - [Debug] 0x00007fffffbfec30 (rsp + 19) = 0xffffffffffe373c4
2026-02-21 12:55:03.126 - [Warn] [task "/sbin/init" (pid 1)]: Fault : Exception number : 13 ; Error : GENERAL_PROTECTION_FAULT ; Error code = 0xedc0 ; cr2 = 0x0 ; cr3 = 0x2e4b000 ; rip = 0xffffffffffe2d497
2026-02-21 12:55:03.128 - [Warn] CS: 0x0000000000000008 DS: 0x0000000000000010 SS: 0x0000000000000010
2026-02-21 12:55:03.129 - [Info] FS BASE: 0x00000000008bf9e0 GS BASE: 0x0000000000000000 KERNEL GS BASE: 0xffffffffffe43190
2026-02-21 12:55:03.130 - [Fatal] Kernel panic
2026-02-21 12:55:03.132 - [Info] RSP=0x00007fffffbfed38 RBP=0x00007fffffbfed90 RAX=0x0000000000000038 RBX=0xffff8000029e9df0 RCX=0x0000000000000018 RDX=0x0000000000000060
2026-02-21 12:55:03.134 - [Info] R8=0xffffffffffe11488 R9=0x00007fffffbfed20 R10=0xffff80000001b1c8 R11=0x0000000000000000 R12=0xffffffffffe1f981 R13=0xffffffffffe373c4 R14=0xffffffffffe37520 R15=0x0000000000000400
2026-02-21 12:55:03.136 - [Info] RDI=0x00007fffffbfed30 RSI=0xffffffffffe09a42
2026-02-21 12:55:03.137 - [Info] FS BASE: 0x00000000008bf9e0 GS BASE: 0x0000000000000000 KERNEL GS BASE: 0xffffffffffe43190
2026-02-21 12:55:03.139 - [Info] Stack trace :
2026-02-21 12:55:03.140 - [Info] rip : 0xffffffffffe2d497 [iretq_instruction.dont_swapgs2]
2026-02-21 12:55:03.142 - [Info] rip : 0xffff8000029ec020 | rbp : 0x7fffffbfed90 If i uncomment the line that disabled signals (by not pushing the new context) the code works (and no signal is generated) so it means the stack itself isn't wrong.
I hope someone can see what could be happening because this is very annoying and i really have no idea what to do
