From 82008074983f9133ce0daf58c0faa2ebbb5f4e94 Mon Sep 17 00:00:00 2001 From: Michalis Pappas Date: Tue, 2 Jan 2024 18:53:21 +0100 Subject: [PATCH] lib/posix-process/signal: Add sigaltstack() sigaltstack() allows setting or retrieving an alternative signal stack context. For more info see sigaltstack(2) Signed-off-by: Michalis Pappas Reviewed-by: Ioan-Teodor Teugea Reviewed-by: Sergiu Moga Reviewed-by: Andrei Tatar Approved-by: Andrei Tatar GitHub-Closes: #1248 --- lib/posix-process/Makefile.uk | 2 + lib/posix-process/exportsyms.uk | 1 + lib/posix-process/signal/sigaltstack.c | 71 ++++++++++++++++++++++++++ lib/posix-process/signal/signal.c | 2 + lib/posix-process/signal/signal.h | 1 + 5 files changed, 77 insertions(+) create mode 100644 lib/posix-process/signal/sigaltstack.c diff --git a/lib/posix-process/Makefile.uk b/lib/posix-process/Makefile.uk index 977e42f66..4d4b6b714 100644 --- a/lib/posix-process/Makefile.uk +++ b/lib/posix-process/Makefile.uk @@ -20,6 +20,7 @@ LIBPOSIX_PROCESS_SRCS-y += $(LIBPOSIX_PROCESS_BASE)/wait.c LIBPOSIX_PROCESS_SRCS-y += $(LIBPOSIX_PROCESS_BASE)/signals.c LIBPOSIX_PROCESS_SRCS-$(CONFIG_LIBPOSIX_PROCESS_SIGNAL) += $(LIBPOSIX_PROCESS_BASE)/signal/signal.c +LIBPOSIX_PROCESS_SRCS-y += $(LIBPOSIX_PROCESS_BASE)/signal/sigaltstack.c LIBPOSIX_PROCESS_SRCS-y += $(LIBPOSIX_PROCESS_BASE)/signal/rt_sigprocmask.c LIBPOSIX_PROCESS_SRCS-y += $(LIBPOSIX_PROCESS_BASE)/signal/rt_sigaction.c @@ -35,6 +36,7 @@ LIBPOSIX_PROCESS_CXXINCLUDES-y += -I$(UK_PLAT_COMMON_BASE)/include UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_PROCESS_CLONE) += clone-5e UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_PROCESS_EXECVE) += execve-3e +UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_PROCESS) += sigaltstack-2 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_PROCESS) += rt_sigprocmask-4 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_PROCESS) += rt_sigaction-4 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_PROCESS_VFORK) += vfork-2e diff --git a/lib/posix-process/exportsyms.uk b/lib/posix-process/exportsyms.uk index f7cf4baff..7a705d2c8 100644 --- a/lib/posix-process/exportsyms.uk +++ b/lib/posix-process/exportsyms.uk @@ -42,4 +42,5 @@ uk_posix_process_create uk_posix_process_kill clone vfork +sigaltstack sigprocmask diff --git a/lib/posix-process/signal/sigaltstack.c b/lib/posix-process/signal/sigaltstack.c new file mode 100644 index 000000000..3fe155342 --- /dev/null +++ b/lib/posix-process/signal/sigaltstack.c @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright (c) 2023, Unikraft GmbH and The Unikraft Authors. + * Licensed under the BSD-3-Clause License (the "License"). + * You may not use this file except in compliance with the License. + */ + +#include +#include +#include +#include + +#include +#include + +#include "signal.h" + +#if CONFIG_LIBPOSIX_PROCESS_SIGNAL +UK_SYSCALL_R_DEFINE(int, sigaltstack, const stack_t *, ss, + stack_t *, old_ss) +{ + struct posix_process *proc; + + proc = uk_pprocess_current(); + UK_ASSERT(proc); + + if (ss) { + if (unlikely(ss->ss_flags && + !((unsigned int)ss->ss_flags == SS_AUTODISARM || + (unsigned int)ss->ss_flags == SS_DISABLE))) + return -EINVAL; + + if (unlikely(ss->ss_size < MINSIGSTKSZ)) + return -ENOMEM; + + /* See BUGS in SIGALTSTACK(2) */ + if (unlikely(ss->ss_flags & SS_ONSTACK)) + return -EPERM; + + if (unlikely(proc->signal->altstack.ss_flags == SS_ONSTACK)) + return -EPERM; + + if ((unsigned int)ss->ss_flags == SS_AUTODISARM) + uk_pr_warn("SS_AUTODISARM stubbed\n"); + + if ((unsigned int)ss->ss_flags == SS_DISABLE) { + proc->signal->altstack.ss_flags |= SS_DISABLE; + return 0; + } + + /* TODO Don't allow updating the altstack if we are executing + * on it already. + */ + + proc->signal->altstack = *ss; + } + + if (old_ss) + *old_ss = proc->signal->altstack; + + return 0; +} + +#else /* !CONFIG_LIBPOSIX_PROCESS_SIGNAL */ + +UK_SYSCALL_R_DEFINE(int, sigaltstack, const stack_t *, ss, + stack_t *, old_ss) +{ + UK_WARN_STUBBED(); + return 0; +} +#endif /* !CONFIG_LIBPOSIX_PROCESS_SIGNAL */ diff --git a/lib/posix-process/signal/signal.c b/lib/posix-process/signal/signal.c index 20b6ccaa3..924f449c1 100644 --- a/lib/posix-process/signal/signal.c +++ b/lib/posix-process/signal/signal.c @@ -214,6 +214,8 @@ int pprocess_signal_pdesc_init(struct posix_process *process) pprocess_signal_foreach(signum) pprocess_signal_sigaction_clear(KERN_SIGACTION(process, signum)); + pd->altstack.ss_flags = SS_DISABLE; + return 0; } diff --git a/lib/posix-process/signal/signal.h b/lib/posix-process/signal/signal.h index bb6b7e518..d1695ed98 100644 --- a/lib/posix-process/signal/signal.h +++ b/lib/posix-process/signal/signal.h @@ -155,6 +155,7 @@ struct uk_signal_queue { struct uk_signal_pdesc { __sz queued_count; __sz queued_max; + stack_t altstack; struct uk_signal_queue sigqueue; /* We use dynamically allocated memory for sigaction as passing * CLONE_SIGHAND to clone() requires that the parent and the child -- 2.39.5