* [PATCH] clone: fix CLONE_PIDFD support
@ 2019-07-14 12:02 Dmitry V. Levin
2019-07-14 12:17 ` Christian Brauner
0 siblings, 1 reply; 7+ messages in thread
From: Dmitry V. Levin @ 2019-07-14 12:02 UTC (permalink / raw)
To: Christian Brauner; +Cc: Anatoly Pugachev, linux-kernel
The introduction of clone3 syscall accidentally broke CLONE_PIDFD
support in traditional clone syscall on compat x86 and those
architectures that use do_fork to implement clone syscall.
This bug was found by strace test suite.
Link: https://strace.io/logs/strace/2019-07-12
Fixes: 7f192e3cd316 ("fork: add clone3")
Bisected-and-tested-by: Anatoly Pugachev <matorola@gmail.com>
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
---
arch/x86/ia32/sys_ia32.c | 1 +
kernel/fork.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c
index 64a6c952091e..98754baf411a 100644
--- a/arch/x86/ia32/sys_ia32.c
+++ b/arch/x86/ia32/sys_ia32.c
@@ -239,6 +239,7 @@ COMPAT_SYSCALL_DEFINE5(x86_clone, unsigned long, clone_flags,
{
struct kernel_clone_args args = {
.flags = (clone_flags & ~CSIGNAL),
+ .pidfd = parent_tidptr,
.child_tid = child_tidptr,
.parent_tid = parent_tidptr,
.exit_signal = (clone_flags & CSIGNAL),
diff --git a/kernel/fork.c b/kernel/fork.c
index 8f3e2d97d771..2c3cbad807b6 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -2417,6 +2417,7 @@ long do_fork(unsigned long clone_flags,
{
struct kernel_clone_args args = {
.flags = (clone_flags & ~CSIGNAL),
+ .pidfd = parent_tidptr,
.child_tid = child_tidptr,
.parent_tid = parent_tidptr,
.exit_signal = (clone_flags & CSIGNAL),
--
ldv
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH] clone: fix CLONE_PIDFD support 2019-07-14 12:02 [PATCH] clone: fix CLONE_PIDFD support Dmitry V. Levin @ 2019-07-14 12:17 ` Christian Brauner 2019-07-14 14:10 ` Dmitry V. Levin 0 siblings, 1 reply; 7+ messages in thread From: Christian Brauner @ 2019-07-14 12:17 UTC (permalink / raw) To: Dmitry V. Levin; +Cc: Anatoly Pugachev, linux-kernel On Sun, Jul 14, 2019 at 03:02:06PM +0300, Dmitry V. Levin wrote: > The introduction of clone3 syscall accidentally broke CLONE_PIDFD > support in traditional clone syscall on compat x86 and those > architectures that use do_fork to implement clone syscall. > > This bug was found by strace test suite. > > Link: https://strace.io/logs/strace/2019-07-12 > Fixes: 7f192e3cd316 ("fork: add clone3") > Bisected-and-tested-by: Anatoly Pugachev <matorola@gmail.com> > Signed-off-by: Dmitry V. Levin <ldv@altlinux.org> Good catch! Thank you Dmitry. One change request below. > --- > arch/x86/ia32/sys_ia32.c | 1 + > kernel/fork.c | 1 + > 2 files changed, 2 insertions(+) > > diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c > index 64a6c952091e..98754baf411a 100644 > --- a/arch/x86/ia32/sys_ia32.c > +++ b/arch/x86/ia32/sys_ia32.c > @@ -239,6 +239,7 @@ COMPAT_SYSCALL_DEFINE5(x86_clone, unsigned long, clone_flags, > { > struct kernel_clone_args args = { > .flags = (clone_flags & ~CSIGNAL), > + .pidfd = parent_tidptr, > .child_tid = child_tidptr, > .parent_tid = parent_tidptr, > .exit_signal = (clone_flags & CSIGNAL), > diff --git a/kernel/fork.c b/kernel/fork.c > index 8f3e2d97d771..2c3cbad807b6 100644 > --- a/kernel/fork.c > +++ b/kernel/fork.c > @@ -2417,6 +2417,7 @@ long do_fork(unsigned long clone_flags, > { > struct kernel_clone_args args = { > .flags = (clone_flags & ~CSIGNAL), > + .pidfd = parent_tidptr, > .child_tid = child_tidptr, > .parent_tid = parent_tidptr, > .exit_signal = (clone_flags & CSIGNAL), > -- Both of these legacy clone helpers need to make CLONE_PIDFD and CLONE_PARENT_SETTID incompatible, i.e. could you please add a helper to kernel/fork.c: bool legacy_clone_args_valid(const struct kernel_clone_args *kargs) { /* clone(CLONE_PIDFD) uses parent_tidptr to return a pidfd */ if ((kargs->flags & CLONE_PIDFD) && (kargs->flags & CLONE_PARENT_SETTID)) return false; } and export it and use it in ia32 too? Then resend and I'll put it into my tree that already has a few other fixes about to be sent. Christian ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] clone: fix CLONE_PIDFD support 2019-07-14 12:17 ` Christian Brauner @ 2019-07-14 14:10 ` Dmitry V. Levin 2019-07-14 14:23 ` Christian Brauner 0 siblings, 1 reply; 7+ messages in thread From: Dmitry V. Levin @ 2019-07-14 14:10 UTC (permalink / raw) To: Christian Brauner; +Cc: Anatoly Pugachev, linux-kernel [-- Attachment #1: Type: text/plain, Size: 2423 bytes --] On Sun, Jul 14, 2019 at 02:17:25PM +0200, Christian Brauner wrote: > On Sun, Jul 14, 2019 at 03:02:06PM +0300, Dmitry V. Levin wrote: > > The introduction of clone3 syscall accidentally broke CLONE_PIDFD > > support in traditional clone syscall on compat x86 and those > > architectures that use do_fork to implement clone syscall. > > > > This bug was found by strace test suite. > > > > Link: https://strace.io/logs/strace/2019-07-12 > > Fixes: 7f192e3cd316 ("fork: add clone3") > > Bisected-and-tested-by: Anatoly Pugachev <matorola@gmail.com> > > Signed-off-by: Dmitry V. Levin <ldv@altlinux.org> > > Good catch! Thank you Dmitry. > > One change request below. > > > --- > > arch/x86/ia32/sys_ia32.c | 1 + > > kernel/fork.c | 1 + > > 2 files changed, 2 insertions(+) > > > > diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c > > index 64a6c952091e..98754baf411a 100644 > > --- a/arch/x86/ia32/sys_ia32.c > > +++ b/arch/x86/ia32/sys_ia32.c > > @@ -239,6 +239,7 @@ COMPAT_SYSCALL_DEFINE5(x86_clone, unsigned long, clone_flags, > > { > > struct kernel_clone_args args = { > > .flags = (clone_flags & ~CSIGNAL), > > + .pidfd = parent_tidptr, > > .child_tid = child_tidptr, > > .parent_tid = parent_tidptr, > > .exit_signal = (clone_flags & CSIGNAL), > > diff --git a/kernel/fork.c b/kernel/fork.c > > index 8f3e2d97d771..2c3cbad807b6 100644 > > --- a/kernel/fork.c > > +++ b/kernel/fork.c > > @@ -2417,6 +2417,7 @@ long do_fork(unsigned long clone_flags, > > { > > struct kernel_clone_args args = { > > .flags = (clone_flags & ~CSIGNAL), > > + .pidfd = parent_tidptr, > > .child_tid = child_tidptr, > > .parent_tid = parent_tidptr, > > .exit_signal = (clone_flags & CSIGNAL), > > -- > > Both of these legacy clone helpers need to make CLONE_PIDFD and > CLONE_PARENT_SETTID incompatible, i.e. could you please add a helper to > kernel/fork.c: > > bool legacy_clone_args_valid(const struct kernel_clone_args *kargs) > { > /* clone(CLONE_PIDFD) uses parent_tidptr to return a pidfd */ > if ((kargs->flags & CLONE_PIDFD) && (kargs->flags & CLONE_PARENT_SETTID)) > return false; > } > > and export it and use it in ia32 too? copy_process already performs the check, isn't this enough? Also, the check in sys_clone looks redundant and I was going to suggest its removal. -- ldv [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 801 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] clone: fix CLONE_PIDFD support 2019-07-14 14:10 ` Dmitry V. Levin @ 2019-07-14 14:23 ` Christian Brauner 2019-07-14 16:14 ` Dmitry V. Levin 0 siblings, 1 reply; 7+ messages in thread From: Christian Brauner @ 2019-07-14 14:23 UTC (permalink / raw) To: Dmitry V. Levin; +Cc: Anatoly Pugachev, linux-kernel On Sun, Jul 14, 2019 at 05:10:08PM +0300, Dmitry V. Levin wrote: > On Sun, Jul 14, 2019 at 02:17:25PM +0200, Christian Brauner wrote: > > On Sun, Jul 14, 2019 at 03:02:06PM +0300, Dmitry V. Levin wrote: > > > The introduction of clone3 syscall accidentally broke CLONE_PIDFD > > > support in traditional clone syscall on compat x86 and those > > > architectures that use do_fork to implement clone syscall. > > > > > > This bug was found by strace test suite. > > > > > > Link: https://strace.io/logs/strace/2019-07-12 > > > Fixes: 7f192e3cd316 ("fork: add clone3") > > > Bisected-and-tested-by: Anatoly Pugachev <matorola@gmail.com> > > > Signed-off-by: Dmitry V. Levin <ldv@altlinux.org> > > > > Good catch! Thank you Dmitry. > > > > One change request below. > > > > > --- > > > arch/x86/ia32/sys_ia32.c | 1 + > > > kernel/fork.c | 1 + > > > 2 files changed, 2 insertions(+) > > > > > > diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c > > > index 64a6c952091e..98754baf411a 100644 > > > --- a/arch/x86/ia32/sys_ia32.c > > > +++ b/arch/x86/ia32/sys_ia32.c > > > @@ -239,6 +239,7 @@ COMPAT_SYSCALL_DEFINE5(x86_clone, unsigned long, clone_flags, > > > { > > > struct kernel_clone_args args = { > > > .flags = (clone_flags & ~CSIGNAL), > > > + .pidfd = parent_tidptr, > > > .child_tid = child_tidptr, > > > .parent_tid = parent_tidptr, > > > .exit_signal = (clone_flags & CSIGNAL), > > > diff --git a/kernel/fork.c b/kernel/fork.c > > > index 8f3e2d97d771..2c3cbad807b6 100644 > > > --- a/kernel/fork.c > > > +++ b/kernel/fork.c > > > @@ -2417,6 +2417,7 @@ long do_fork(unsigned long clone_flags, > > > { > > > struct kernel_clone_args args = { > > > .flags = (clone_flags & ~CSIGNAL), > > > + .pidfd = parent_tidptr, > > > .child_tid = child_tidptr, > > > .parent_tid = parent_tidptr, > > > .exit_signal = (clone_flags & CSIGNAL), > > > -- > > > > Both of these legacy clone helpers need to make CLONE_PIDFD and > > CLONE_PARENT_SETTID incompatible, i.e. could you please add a helper to > > kernel/fork.c: > > > > bool legacy_clone_args_valid(const struct kernel_clone_args *kargs) > > { > > /* clone(CLONE_PIDFD) uses parent_tidptr to return a pidfd */ > > if ((kargs->flags & CLONE_PIDFD) && (kargs->flags & CLONE_PARENT_SETTID)) > > return false; > > } > > > > and export it and use it in ia32 too? > > copy_process already performs the check, isn't this enough? No it doesn't anymore. clone3() allows CLONE_PIDFD + CLONE_PARENT_SETTID since struct clone_args has a dedicated pidfd return argument. > Also, the check in sys_clone looks redundant and I was going to suggest > its removal. See above. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] clone: fix CLONE_PIDFD support 2019-07-14 14:23 ` Christian Brauner @ 2019-07-14 16:14 ` Dmitry V. Levin 2019-07-14 16:20 ` [PATCH v2] " Dmitry V. Levin 0 siblings, 1 reply; 7+ messages in thread From: Dmitry V. Levin @ 2019-07-14 16:14 UTC (permalink / raw) To: Christian Brauner; +Cc: Anatoly Pugachev, linux-kernel [-- Attachment #1: Type: text/plain, Size: 2963 bytes --] On Sun, Jul 14, 2019 at 04:23:05PM +0200, Christian Brauner wrote: > On Sun, Jul 14, 2019 at 05:10:08PM +0300, Dmitry V. Levin wrote: > > On Sun, Jul 14, 2019 at 02:17:25PM +0200, Christian Brauner wrote: > > > On Sun, Jul 14, 2019 at 03:02:06PM +0300, Dmitry V. Levin wrote: > > > > The introduction of clone3 syscall accidentally broke CLONE_PIDFD > > > > support in traditional clone syscall on compat x86 and those > > > > architectures that use do_fork to implement clone syscall. > > > > > > > > This bug was found by strace test suite. > > > > > > > > Link: https://strace.io/logs/strace/2019-07-12 > > > > Fixes: 7f192e3cd316 ("fork: add clone3") > > > > Bisected-and-tested-by: Anatoly Pugachev <matorola@gmail.com> > > > > Signed-off-by: Dmitry V. Levin <ldv@altlinux.org> > > > > > > Good catch! Thank you Dmitry. > > > > > > One change request below. > > > > > > > --- > > > > arch/x86/ia32/sys_ia32.c | 1 + > > > > kernel/fork.c | 1 + > > > > 2 files changed, 2 insertions(+) > > > > > > > > diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c > > > > index 64a6c952091e..98754baf411a 100644 > > > > --- a/arch/x86/ia32/sys_ia32.c > > > > +++ b/arch/x86/ia32/sys_ia32.c > > > > @@ -239,6 +239,7 @@ COMPAT_SYSCALL_DEFINE5(x86_clone, unsigned long, clone_flags, > > > > { > > > > struct kernel_clone_args args = { > > > > .flags = (clone_flags & ~CSIGNAL), > > > > + .pidfd = parent_tidptr, > > > > .child_tid = child_tidptr, > > > > .parent_tid = parent_tidptr, > > > > .exit_signal = (clone_flags & CSIGNAL), > > > > diff --git a/kernel/fork.c b/kernel/fork.c > > > > index 8f3e2d97d771..2c3cbad807b6 100644 > > > > --- a/kernel/fork.c > > > > +++ b/kernel/fork.c > > > > @@ -2417,6 +2417,7 @@ long do_fork(unsigned long clone_flags, > > > > { > > > > struct kernel_clone_args args = { > > > > .flags = (clone_flags & ~CSIGNAL), > > > > + .pidfd = parent_tidptr, > > > > .child_tid = child_tidptr, > > > > .parent_tid = parent_tidptr, > > > > .exit_signal = (clone_flags & CSIGNAL), > > > > -- > > > > > > Both of these legacy clone helpers need to make CLONE_PIDFD and > > > CLONE_PARENT_SETTID incompatible, i.e. could you please add a helper to > > > kernel/fork.c: > > > > > > bool legacy_clone_args_valid(const struct kernel_clone_args *kargs) > > > { > > > /* clone(CLONE_PIDFD) uses parent_tidptr to return a pidfd */ > > > if ((kargs->flags & CLONE_PIDFD) && (kargs->flags & CLONE_PARENT_SETTID)) > > > return false; > > > } > > > > > > and export it and use it in ia32 too? > > > > copy_process already performs the check, isn't this enough? > > No it doesn't anymore. clone3() allows CLONE_PIDFD + CLONE_PARENT_SETTID > since struct clone_args has a dedicated pidfd return argument. Indeed, I must've missed it, thanks. OK, I'll send a new fix with legacy_clone_args_valid. -- ldv [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 801 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2] clone: fix CLONE_PIDFD support 2019-07-14 16:14 ` Dmitry V. Levin @ 2019-07-14 16:20 ` Dmitry V. Levin 2019-07-14 18:21 ` Christian Brauner 0 siblings, 1 reply; 7+ messages in thread From: Dmitry V. Levin @ 2019-07-14 16:20 UTC (permalink / raw) To: Christian Brauner; +Cc: Anatoly Pugachev, linux-kernel The introduction of clone3 syscall accidentally broke CLONE_PIDFD support in traditional clone syscall on compat x86 and those architectures that use do_fork to implement clone syscall. This bug was found by strace test suite. Link: https://strace.io/logs/strace/2019-07-12 Fixes: 7f192e3cd316 ("fork: add clone3") Bisected-and-tested-by: Anatoly Pugachev <matorola@gmail.com> Signed-off-by: Dmitry V. Levin <ldv@altlinux.org> --- arch/x86/ia32/sys_ia32.c | 4 ++++ include/linux/sched/task.h | 1 + kernel/fork.c | 17 +++++++++++++++-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c index 64a6c952091e..21790307121e 100644 --- a/arch/x86/ia32/sys_ia32.c +++ b/arch/x86/ia32/sys_ia32.c @@ -239,6 +239,7 @@ COMPAT_SYSCALL_DEFINE5(x86_clone, unsigned long, clone_flags, { struct kernel_clone_args args = { .flags = (clone_flags & ~CSIGNAL), + .pidfd = parent_tidptr, .child_tid = child_tidptr, .parent_tid = parent_tidptr, .exit_signal = (clone_flags & CSIGNAL), @@ -246,5 +247,8 @@ COMPAT_SYSCALL_DEFINE5(x86_clone, unsigned long, clone_flags, .tls = tls_val, }; + if (!legacy_clone_args_valid(&args)) + return -EINVAL; + return _do_fork(&args); } diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h index 109a0df5af39..0497091e40c1 100644 --- a/include/linux/sched/task.h +++ b/include/linux/sched/task.h @@ -89,6 +89,7 @@ extern void exit_files(struct task_struct *); extern void exit_itimers(struct signal_struct *); extern long _do_fork(struct kernel_clone_args *kargs); +extern bool legacy_clone_args_valid(const struct kernel_clone_args *kargs); extern long do_fork(unsigned long, unsigned long, unsigned long, int __user *, int __user *); struct task_struct *fork_idle(int); struct mm_struct *copy_init_mm(void); diff --git a/kernel/fork.c b/kernel/fork.c index 8f3e2d97d771..ef1e05a68827 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -2406,6 +2406,16 @@ long _do_fork(struct kernel_clone_args *args) return nr; } +bool legacy_clone_args_valid(const struct kernel_clone_args *kargs) +{ + /* clone(CLONE_PIDFD) uses parent_tidptr to return a pidfd */ + if ((kargs->flags & CLONE_PIDFD) && + (kargs->flags & CLONE_PARENT_SETTID)) + return false; + + return true; +} + #ifndef CONFIG_HAVE_COPY_THREAD_TLS /* For compatibility with architectures that call do_fork directly rather than * using the syscall entry points below. */ @@ -2417,6 +2427,7 @@ long do_fork(unsigned long clone_flags, { struct kernel_clone_args args = { .flags = (clone_flags & ~CSIGNAL), + .pidfd = parent_tidptr, .child_tid = child_tidptr, .parent_tid = parent_tidptr, .exit_signal = (clone_flags & CSIGNAL), @@ -2424,6 +2435,9 @@ long do_fork(unsigned long clone_flags, .stack_size = stack_size, }; + if (!legacy_clone_args_valid(&args)) + return -EINVAL; + return _do_fork(&args); } #endif @@ -2505,8 +2519,7 @@ SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, .tls = tls, }; - /* clone(CLONE_PIDFD) uses parent_tidptr to return a pidfd */ - if ((clone_flags & CLONE_PIDFD) && (clone_flags & CLONE_PARENT_SETTID)) + if (!legacy_clone_args_valid(&args)) return -EINVAL; return _do_fork(&args); -- ldv ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2] clone: fix CLONE_PIDFD support 2019-07-14 16:20 ` [PATCH v2] " Dmitry V. Levin @ 2019-07-14 18:21 ` Christian Brauner 0 siblings, 0 replies; 7+ messages in thread From: Christian Brauner @ 2019-07-14 18:21 UTC (permalink / raw) To: Dmitry V. Levin; +Cc: Anatoly Pugachev, linux-kernel On Sun, Jul 14, 2019 at 07:20:47PM +0300, Dmitry V. Levin wrote: > The introduction of clone3 syscall accidentally broke CLONE_PIDFD > support in traditional clone syscall on compat x86 and those > architectures that use do_fork to implement clone syscall. > > This bug was found by strace test suite. > > Link: https://strace.io/logs/strace/2019-07-12 > Fixes: 7f192e3cd316 ("fork: add clone3") > Bisected-and-tested-by: Anatoly Pugachev <matorola@gmail.com> > Signed-off-by: Dmitry V. Levin <ldv@altlinux.org> This looks good; moving this into my tree. Thanks! Christian ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2019-07-14 18:21 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2019-07-14 12:02 [PATCH] clone: fix CLONE_PIDFD support Dmitry V. Levin 2019-07-14 12:17 ` Christian Brauner 2019-07-14 14:10 ` Dmitry V. Levin 2019-07-14 14:23 ` Christian Brauner 2019-07-14 16:14 ` Dmitry V. Levin 2019-07-14 16:20 ` [PATCH v2] " Dmitry V. Levin 2019-07-14 18:21 ` Christian Brauner
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.