[PATCH v4] clone.2: Fix erroneous statement about CLONE_NEWPID|CLONE_PARENT

Alejandro Colomar
2023-08-13T14:14:32Z

From: Sargun Dhillon <sargun@sargun.me>

CLONE_NEWPID|CLONE_PARENT was only prohibited during a short period.
That prohibition was introduced in Linux 3.12, in commit 40a0d32d1eaf
("fork: unify and tighten up CLONE_NEWUSER/CLONE_NEWPID checks"), but
was a regression, and was fixed in Linux 3.13, in commit 1f7f4dde5c94
("fork: Allow CLONE_PARENT after setns(CLONE_NEWPID)").

In this test program, one can see that it works:

#include <err.h>
#include <linux/sched.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <unistd.h>

static pid_t sys_clone3(struct clone_args *args);

int
main(void)
{
int ret;
struct clone_args args = {
.flags = CLONE_PARENT | CLONE_NEWPID,
};

printf("main program: pid: %d, and ppid: %d\n", getpid(), getppid());

ret = sys_clone3(&args);
switch (ret) {
case -1:
err(EXIT_FAILURE, "clone3");
case 0:
printf("child: pid: %d, and ppid: %d\n", getpid(), getppid());
exit(EXIT_SUCCESS);
default:
exit(EXIT_SUCCESS);
}
}

static pid_t
sys_clone3(struct clone_args *args)
{
fflush(stdout);
fflush(stderr);
return syscall(SYS_clone3, args, sizeof(*args));
}

This test program (successfully) outputs:

# ./a.out
main program: pid: 34663, and ppid: 34662
child: pid: 1, and ppid: 0

Fixes: f00071920ec3 ("clone.2: EINVAL if (CLONE_NEWUSER|CLONE_NEWPID) && (CLONE_THREAD|CLONE_PARENT)")
Cowritten-by: Sargun Dhillon <sargun@sargun.me>
Cc: Serge Hallyn <serge@hallyn.com>
Cc: John Watts <contact@jookia.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
man2/clone.2 | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/man2/clone.2 b/man2/clone.2
index b91b71831..4a75b557b 100644
--- a/man2/clone.2
+++ b/man2/clone.2
@@ -729,23 +729,21 @@ .SS The flags mask
For further information on PID namespaces, see
.BR namespaces (7)
and
.BR pid_namespaces (7).
.IP
Only a privileged process
.RB ( CAP_SYS_ADMIN )
can employ
.BR CLONE_NEWPID .
This flag can't be specified in conjunction with
-.B CLONE_THREAD
-or
-.BR CLONE_PARENT .
+.BR CLONE_THREAD .
.TP
.B CLONE_NEWUSER
(This flag first became meaningful for
.BR clone ()
in Linux 2.6.23,
the current
.BR clone ()
semantics were merged in Linux 3.5,
and the final pieces to make the user namespaces completely usable were
merged in Linux 3.8.)
@@ -1310,32 +1308,37 @@ .SH ERRORS
.B EINVAL
Both
.B CLONE_NEWIPC
and
.B CLONE_SYSVSEM
were specified in the
.I flags
mask.
.TP
.B EINVAL
-One (or both) of
.B CLONE_NEWPID
-or
-.B CLONE_NEWUSER
and one (or both) of
.B CLONE_THREAD
or
.B CLONE_PARENT
were specified in the
.I flags
mask.
.TP
+.B EINVAL
+.B CLONE_NEWUSER
+and
+.B CLONE_THREAD
+were specified in the
+.I flags
+mask.
+.TP
.BR EINVAL " (since Linux 2.6.32)"
.\" commit 123be07b0b399670a7cc3d82fef0cb4f93ef885c
.B CLONE_PARENT
was specified, and the caller is an init process.
.TP
.B EINVAL
Returned by the glibc
.BR clone ()
wrapper function when
.I fn
--
2.40.1