LIBPOSIX_PROCESS_SRCS-y += $(LIBPOSIX_PROCESS_BASE)/signal/rt_sigpending.c
LIBPOSIX_PROCESS_SRCS-y += $(LIBPOSIX_PROCESS_BASE)/signal/rt_sigprocmask.c
LIBPOSIX_PROCESS_SRCS-y += $(LIBPOSIX_PROCESS_BASE)/signal/rt_sigaction.c
+LIBPOSIX_PROCESS_SRCS-y += $(LIBPOSIX_PROCESS_BASE)/signal/rt_sigqueueinfo.c
+LIBPOSIX_PROCESS_SRCS-y += $(LIBPOSIX_PROCESS_BASE)/signal/rt_tgsigqueueinfo.c
+LIBPOSIX_PROCESS_SRCS-y += $(LIBPOSIX_PROCESS_BASE)/signal/kill.c
+LIBPOSIX_PROCESS_SRCS-y += $(LIBPOSIX_PROCESS_BASE)/signal/tgkill.c
+LIBPOSIX_PROCESS_SRCS-y += $(LIBPOSIX_PROCESS_BASE)/signal/tkill.c
LIBPOSIX_PROCESS_SRCS-$(CONFIG_LIBPOSIX_PROCESS_CLONE) += $(LIBPOSIX_PROCESS_BASE)/clone.c
LIBPOSIX_PROCESS_SRCS-$(CONFIG_LIBPOSIX_PROCESS_CLONE) += $(LIBPOSIX_PROCESS_BASE)/clonetab.ld
UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_PROCESS) += rt_sigpending-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) += rt_sigqueueinfo-3
+UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_PROCESS) += rt_tgsigqueueinfo-4
+UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_PROCESS) += kill-2
+UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_PROCESS) += tgkill-3
+UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_PROCESS) += tkill-2
UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_PROCESS_VFORK) += vfork-2e
UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_PROCESS) += wait4-4 waitid-4
UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_PROCESS) += getpgid-1
uk_posix_process_kill
clone
vfork
+kill
sigaltstack
sigprocmask
+tgkill
--- /dev/null
+/* 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 <stddef.h>
+#include <sys/types.h>
+#include <uk/syscall.h>
+
+#include "signal.h"
+
+#if CONFIG_LIBPOSIX_PROCESS_SIGNAL
+UK_SYSCALL_R_DEFINE(int, kill, pid_t, pid, int, signum)
+{
+ return pprocess_signal_process_do(pid, signum, NULL);
+}
+#else /* !CONFIG_LIBPOSIX_PROCESS_SIGNAL */
+UK_SYSCALL_R_DEFINE(int, kill, pid_t, pid, int, signum)
+{
+ UK_WARN_STUBBED();
+ return 0;
+}
+#endif /* !CONFIG_LIBPOSIX_PROCESS_SIGNAL */
--- /dev/null
+/* 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 <errno.h>
+#include <signal.h>
+
+#include <uk/essentials.h>
+#include <uk/process.h>
+#include <uk/syscall.h>
+
+#include "signal.h"
+
+#if CONFIG_LIBPOSIX_PROCESS_SIGNAL
+UK_LLSYSCALL_R_DEFINE(int, rt_sigqueueinfo,
+ int, tgid,
+ int, signum,
+ siginfo_t *, siginfo)
+{
+ if (unlikely(!siginfo))
+ return -EFAULT;
+
+ /* The si_code must be valid when targeting a
+ * different process.
+ */
+ if (unlikely(tgid != uk_sys_getpid() && siginfo->si_code != SI_QUEUE))
+ return -EPERM;
+
+ return pprocess_signal_process_do(tgid, signum, siginfo);
+}
+#else /* !CONFIG_LIBPOSIX_PROCESS_SIGNAL */
+UK_LLSYSCALL_R_DEFINE(int, rt_sigqueueinfo,
+ int, tgid,
+ int, signum,
+ siginfo_t *, siginfo)
+{
+ UK_WARN_STUBBED();
+ return 0;
+}
+#endif /* !CONFIG_LIBPOSIX_PROCESS_SIGNAL */
--- /dev/null
+/* 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 <errno.h>
+#include <signal.h>
+
+#include <uk/essentials.h>
+#include <uk/process.h>
+#include <uk/syscall.h>
+
+#include "signal.h"
+
+#if CONFIG_LIBPOSIX_PROCESS_SIGNAL
+
+UK_LLSYSCALL_R_DEFINE(int, rt_tgsigqueueinfo,
+ int, tgid, int, tid,
+ int, signum, siginfo_t *, siginfo)
+{
+ struct posix_process *proc;
+ struct posix_thread *pthread;
+
+ if (unlikely(!IS_VALID(signum)))
+ return -EINVAL;
+
+ if (unlikely(!siginfo))
+ return -EFAULT;
+
+ pthread = tid2pthread(tid);
+ if (unlikely(!pthread))
+ return -EINVAL;
+
+ /* Make sure tid is part of by tgid */
+ proc = tid2pprocess(tid);
+ if (unlikely(!proc || proc->pid != tgid))
+ return -ESRCH;
+
+ /* The si_code must be valid when targeting a
+ * different process.
+ */
+ if (unlikely(siginfo->si_code != SI_QUEUE))
+ return -EPERM;
+
+ return pprocess_signal_thread_do(tid, signum, siginfo);
+}
+#else /* !CONFIG_LIBPOSIX_PROCESS_SIGNAL */
+UK_LLSYSCALL_R_DEFINE(int, rt_tgsigqueueinfo,
+ int, tgid, int, tid,
+ int, signum, siginfo_t *, siginfo)
+{
+ UK_WARN_STUBBED();
+ return 0;
+}
+#endif /* !CONFIG_LIBPOSIX_PROCESS_SIGNAL */
--- /dev/null
+/* 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.
+ */
+
+#ifndef __UK_PROCESS_SIGINFO_H__
+#define __UK_PROCESS_SIGINFO_H__
+
+#include <signal.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <uk/process.h>
+
+#include "process.h"
+
+static inline void set_siginfo_kill(int signum, siginfo_t *si)
+{
+ UK_ASSERT(si);
+
+ si->si_signo = signum;
+ si->si_code = SI_USER;
+ si->si_pid = uk_sys_getpid();
+ si->si_uid = 0;
+}
+
+static inline void set_siginfo_sigqueue(int signum, siginfo_t *si,
+ siginfo_t *si_usr)
+{
+ UK_ASSERT(si);
+ UK_ASSERT(si_usr);
+
+ si->si_signo = signum;
+
+ /* The remaining fields are set by the caller
+ * without verification.
+ */
+ si->si_code = si_usr->si_code;
+ si->si_pid = si_usr->si_pid;
+ si->si_uid = si_usr->si_uid;
+ si->si_value = si_usr->si_value;
+}
+
+#endif /* __UK_PROCESS_SIGINFO_H__ */
#include "process.h"
#include "sigset.h"
+#include "siginfo.h"
#include "signal.h"
+/* Check permissions to signal target process.
+ *
+ * For a process to be permitted to send a signal to another
+ * process, its real / effective uid must match the target's
+ * real / saved set-user-id. We don't support these, so we
+ * deliver to every process.
+ */
+#define signal_check_perm(_target_process) true
+
/* Enqueue signal for a thread or a process
*
* Setting pthread to NULL signifies that the signal
return 0;
}
+int pprocess_signal_send(struct posix_process *proc, int signum,
+ siginfo_t *siginfo)
+{
+ struct uk_signal *sig;
+ int rc;
+
+ sig = uk_signal_alloc(proc->_a);
+ if (unlikely(!sig)) {
+ uk_pr_err("Could not allocate signal\n");
+ return -EAGAIN;
+ }
+
+ if (siginfo)
+ set_siginfo_sigqueue(signum, &sig->siginfo, siginfo);
+ else
+ set_siginfo_kill(signum, &sig->siginfo);
+
+ rc = pprocess_signal_enqueue(proc, NULL, sig);
+ if (unlikely(rc)) {
+ /* issue a warning as this may be temporary */
+ uk_pr_warn("Could not queue signal\n");
+ uk_signal_free(proc->_a, sig);
+ return -EAGAIN;
+ }
+
+ return 0;
+}
+
+int pprocess_signal_process_do(pid_t pid, int signum, siginfo_t *siginfo)
+{
+ struct posix_process *pproc = NULL;
+ struct posix_thread *thread, *threadn;
+ int rc;
+
+ if (unlikely(signum != 0 && !IS_VALID(signum)))
+ return -EINVAL;
+
+ if (unlikely(signum == SIGSTOP || signum == SIGCONT)) {
+ uk_pr_warn("Process stop / resume not supported. Ignoring\n");
+ return 0;
+ }
+
+ /* pid == 0 -> Send the signal to every process in the process group
+ * of the calling process.
+ * pid < -1 -> Send the signal to every process in the process group
+ * with ID equal to -pid.
+ */
+ if (!pid || pid < -1) {
+ uk_pr_warn("pgroups not supported, delivering to every process\n");
+ pid = -1;
+ }
+
+ /* pid == -1 -> Send the signal to every process for which the
+ * calling process has permissions to signal.
+ */
+ if (pid == -1) {
+ uk_pprocess_foreach(pproc) {
+ if (!signal_check_perm(pproc))
+ continue;
+
+ if (IS_IGNORED(pproc, signum))
+ continue;
+
+ rc = pprocess_signal_send(pproc, signum, siginfo);
+ if (unlikely(rc))
+ return rc;
+ }
+ return 0;
+ }
+
+ /* Default: Send to process with pid */
+ pproc = pid2pprocess(pid);
+ if (unlikely(!pproc))
+ return -ESRCH;
+
+ if (unlikely(signal_check_perm(pproc) == false))
+ return -EPERM;
+
+ /* If signum == 0 do only pid exist & permissions check */
+ if (!signum)
+ return 0;
+
+ /* If this signal is currently ignored, don't even try */
+ if (IS_IGNORED(pproc, signum))
+ return 0;
+
+ rc = pprocess_signal_send(pproc, signum, siginfo);
+ if (unlikely(rc))
+ return rc;
+
+ /* Wake up any threads that may be paused */
+ uk_pprocess_foreach_pthread(pproc, thread, threadn) {
+ if (thread->state == POSIX_THREAD_BLOCKED_SIGNAL)
+ uk_semaphore_up(&thread->signal->deliver_semaphore);
+ }
+
+ return 0;
+}
+
+int pprocess_signal_thread_do(int tid, int signum, siginfo_t *siginfo)
+{
+ struct posix_thread *pthread;
+ struct posix_process *pproc;
+ struct uk_signal *sig;
+ int rc;
+
+ pthread = tid2pthread(tid);
+ if (unlikely(!pthread))
+ return -EINVAL;
+
+ pproc = tid2pprocess(tid);
+ UK_ASSERT(pproc);
+
+ sig = uk_signal_alloc(pthread->_a);
+ if (unlikely(!sig)) {
+ uk_pr_err("Could not allocate signal\n");
+ return -EAGAIN;
+ }
+
+ if (siginfo)
+ set_siginfo_sigqueue(signum, &sig->siginfo, siginfo);
+ else
+ set_siginfo_kill(signum, &sig->siginfo);
+
+ rc = pprocess_signal_enqueue(pproc, pthread, sig);
+ if (unlikely(rc)) {
+ /* issue a warning as this may be temporary */
+ uk_pr_warn("Could not queue signal\n");
+ uk_signal_free(pthread->_a, sig);
+ return rc;
+ }
+
+ if (pthread->state == POSIX_THREAD_BLOCKED_SIGNAL)
+ uk_semaphore_up(&pthread->signal->deliver_semaphore);
+
+ return 0;
+}
+
int pprocess_signal_pdesc_alloc(struct posix_process *process)
{
UK_ASSERT(process);
/* Get next pending signal of a given thread */
struct uk_signal *pprocess_signal_next_pending_t(struct posix_thread *pthread);
+/* Signal a process (abstraction for kill / sigqueueinfo) */
+int pprocess_signal_process_do(pid_t pid, int signum, siginfo_t *siginfo);
+
+/* Signal a thread (abstraction for kill / sigqueueinfo) */
+int pprocess_signal_thread_do(int tid, int signum, siginfo_t *siginfo);
+
+/* Signal a process */
+int pprocess_signal_send(struct posix_process *proc, int signum,
+ siginfo_t *siginfo);
#endif /* CONFIG_LIBPOSIX_PROCESS_PIDS */
#endif /* __UK_PROCESS_SIGNAL_H__ */
--- /dev/null
+/* 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 <errno.h>
+
+#include <uk/process.h>
+#include <uk/syscall.h>
+
+#include "signal.h"
+
+#if CONFIG_LIBPOSIX_PROCESS_SIGNAL
+UK_SYSCALL_R_DEFINE(int, tgkill, int, tgid,
+ int, tid, int, signum)
+{
+ struct posix_process *pproc;
+
+ /* Chack tid is part of my tgid */
+ pproc = tid2pprocess(tid);
+ if (unlikely(!pproc || pproc->pid != tgid))
+ return -ESRCH;
+
+ return pprocess_signal_thread_do(tid, signum, NULL);
+}
+#else /* !CONFIG_LIBPOSIX_PROCESS_SIGNAL */
+UK_SYSCALL_R_DEFINE(int, tgkill, int, tgid,
+ int, tid, int, signum)
+{
+ UK_WARN_STUBBED();
+ return 0;
+}
+#endif /* !CONFIG_LIBPOSIX_PROCESS_SIGNAL */
--- /dev/null
+/* 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 <stddef.h>
+#include <uk/syscall.h>
+
+#include "signal.h"
+
+#if CONFIG_LIBPOSIX_PROCESS_SIGNAL
+UK_LLSYSCALL_R_DEFINE(int, tkill, int, tid, int, signum)
+{
+ return pprocess_signal_thread_do(tid, signum, NULL);
+}
+#else /* !CONFIG_LIBPOSIX_PROCESS_SIGNAL */
+UK_LLSYSCALL_R_DEFINE(int, tkill, int, tid, int, signum)
+{
+ UK_WARN_STUBBED();
+ return 0;
+}
+#endif /* !CONFIG_LIBPOSIX_PROCESS_SIGNAL */