From 7314cf708cf0d5589e8d7406c2fd6aca5a580232 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Sat, 28 Jun 2025 20:14:06 +0300 Subject: [PATCH] Kernel: Only restart certain syscalls with SA_RESTART SA_RESTART is not supposted to restart every function. --- kernel/kernel/Syscall.cpp | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/kernel/kernel/Syscall.cpp b/kernel/kernel/Syscall.cpp index b99ea1df..39a7bf1b 100644 --- a/kernel/kernel/Syscall.cpp +++ b/kernel/kernel/Syscall.cpp @@ -38,6 +38,8 @@ namespace Kernel #undef O }; + static bool is_restartable_syscall(int syscall); + extern "C" long cpp_syscall_handler(int syscall, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, InterruptStack* interrupt_stack) { ASSERT(GDT::is_user_segment(interrupt_stack->cs)); @@ -93,7 +95,7 @@ namespace Kernel auto& current_thread = Thread::current(); if (current_thread.can_add_signal_to_execute()) if (current_thread.handle_signal()) - if (ret.is_error() && ret.error().get_error_code() == EINTR) + if (ret.is_error() && ret.error().get_error_code() == EINTR && is_restartable_syscall(syscall)) ret = BAN::Error::from_errno(ERESTART); Processor::set_interrupt_state(InterruptState::Disabled); @@ -105,4 +107,26 @@ namespace Kernel return ret.value(); } + bool is_restartable_syscall(int syscall) + { + // https://www.man7.org/linux/man-pages/man7/signal.7.html + // Interruption of system calls and library functions by signal handlers + switch (syscall) + { + case SYS_READ: + case SYS_WRITE: + case SYS_IOCTL: + case SYS_OPENAT: + case SYS_WAIT: + case SYS_ACCEPT: + case SYS_CONNECT: + case SYS_RECVFROM: + case SYS_SENDTO: + case SYS_FLOCK: + return true; + default: + return false; + } + } + }