From: Jack Pearson Date: Tue, 28 Feb 2023 23:42:46 +0000 (-0800) Subject: clone.2: Note EINVAL when exit_signal + bad flags X-Git-Tag: man-pages-6.04~95 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=184ecd225079567aa3dede2b63c7ddf962cfdbdf;p=thirdparty%2Fman-pages.git 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 #include #include #include #include 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 #include #include #include 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 Cc: "Carlos O'Donell" Signed-off-by: Alejandro Colomar --- 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.