summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@home.osdl.org>2003-08-13 21:11:39 -0700
committerLinus Torvalds <torvalds@home.osdl.org>2003-08-13 21:11:39 -0700
commit856c781e96c564bf22c3a9c49eabb09563e3bf23 (patch)
treef6746a00f365a839cdc09722c61031061c6d142c
parent7ea448d5256a3a0c058ece8e3eddf28c16a72d34 (diff)
Mark CLONE_DETACHED as being irrelevant: it must match CLONE_THREAD.
CLONE_THREAD without CLONE_DETACHED will now return -EINVAL, and for a while we will warn about anything that uses it (there are no known users, but this will help pinpoint any problems if somebody used to care about the invalid combination).
-rw-r--r--include/linux/sched.h2
-rw-r--r--kernel/fork.c21
2 files changed, 17 insertions, 6 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 70eb61ecf4a3..4c96f1df2e5c 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -49,7 +49,7 @@ struct exec_domain;
#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
#define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
#define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
-#define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
+#define CLONE_DETACHED 0x00400000 /* Not used - CLONE_THREAD implies detached uniquely */
#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
#define CLONE_STOPPED 0x02000000 /* Start in stopped state */
diff --git a/kernel/fork.c b/kernel/fork.c
index 7c4c94b1a968..1164d51d897f 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -746,8 +746,22 @@ struct task_struct *copy_process(unsigned long clone_flags,
*/
if ((clone_flags & CLONE_THREAD) && !(clone_flags & CLONE_SIGHAND))
return ERR_PTR(-EINVAL);
- if ((clone_flags & CLONE_DETACHED) && !(clone_flags & CLONE_THREAD))
+
+ /*
+ * CLONE_DETACHED must match CLONE_THREAD: it's a historical
+ * thing.
+ */
+ if (!(clone_flags & CLONE_DETACHED) != !(clone_flags & CLONE_THREAD)) {
+ /* Warn about the old no longer supported case so that we see it */
+ if (clone_flags & CLONE_THREAD) {
+ static int count;
+ if (count < 5) {
+ count++;
+ printk(KERN_WARNING "%s trying to use CLONE_THREAD without CLONE_DETACH\n", current->comm);
+ }
+ }
return ERR_PTR(-EINVAL);
+ }
retval = security_task_create(clone_flags);
if (retval)
@@ -877,10 +891,7 @@ struct task_struct *copy_process(unsigned long clone_flags,
p->parent_exec_id = p->self_exec_id;
/* ok, now we should be set up.. */
- if (clone_flags & CLONE_DETACHED)
- p->exit_signal = -1;
- else
- p->exit_signal = clone_flags & CSIGNAL;
+ p->exit_signal = (clone_flags & CLONE_THREAD) ? -1 : (clone_flags & CSIGNAL);
p->pdeath_signal = 0;
/*