aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Pearson <jack@pearson.onl>2023-02-28 15:42:46 -0800
committerAlejandro Colomar <alx@kernel.org>2023-03-01 22:28:32 +0100
commit184ecd225079567aa3dede2b63c7ddf962cfdbdf (patch)
tree8f9bc2202956e5eb3d53123d6e5096354903bed5
parentb2a916b48219db3ce744b991425fbae1fb7a3baf (diff)
downloadman-pages-184ecd225079567aa3dede2b63c7ddf962cfdbdf.tar.gz
clone.2: Note EINVAL when exit_signal + bad flags
Document that Linux will report EINVAL when exit_signal is specified and either CLONE_THREAD or CLONE_PARENT is specified. From clone3_args_valid in Linux: ``` if ((kargs->flags & (CLONE_THREAD | CLONE_PARENT)) && kargs->exit_signal) return false; ``` I have verified that this happens on my kernel with a small program: ``` #include <stdio.h> #include <linux/sched.h> #include <signal.h> #include <sys/syscall.h> #include <unistd.h> int main(void) { struct clone_args ca = { .flags = CLONE_THREAD | CLONE_SIGHAND | CLONE_VM, .exit_signal = SIGCHLD, // comment me out to fix error .set_tid_size = 0, }; syscall(SYS_clone3, &ca, sizeof(struct clone_args)); perror(""); } ``` And I have verified that this doesn't happen with normal `clone` through the glibc helper: ``` #define _GNU_SOURCE #include <sched.h> #include <signal.h> #include <stdio.h> #include <sys/mman.h> int do_nothing(void *_) { return 0; } int main(void) { void *map = mmap(NULL, 0x10000, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); void *stack_top = map + 0x10000 - 1; clone(do_nothing, stack_top, CLONE_THREAD | CLONE_VM | CLONE_SIGHAND | SIGCHLD, NULL); perror(""); } ``` Signed-off-by: Jack Pearson <jack@pearson.onl> Cc: "Carlos O'Donell" <carlos@redhat.com> Signed-off-by: Alejandro Colomar <alx@kernel.org>
-rw-r--r--man2/clone.210
1 files changed, 10 insertions, 0 deletions
diff --git a/man2/clone.2 b/man2/clone.2
index d63895189e..be802a2800 100644
--- a/man2/clone.2
+++ b/man2/clone.2
@@ -1436,6 +1436,16 @@ One of the PIDs specified in
.I set_tid
was an invalid.
.TP
+.BR EINVAL " (" clone3 "() only)"
+.\" commit 7f192e3cd316ba58c88dfa26796cf77789dd9872
+.B CLONE_THREAD
+or
+.B CLONE_PARENT
+was specified in the
+.I flags
+mask, but a signal was specified in
+.I exit_signal.
+.TP
.BR EINVAL " (AArch64 only, Linux 4.6 and earlier)"
.I stack
was not aligned to a 128-bit boundary.