diff options
Diffstat (limited to 'kernel/fork.c')
| -rw-r--r-- | kernel/fork.c | 76 |
1 files changed, 30 insertions, 46 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index b99d73e971a4..abb3ed6298f6 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | #include <linux/swap.h> | 37 | #include <linux/swap.h> |
| 38 | #include <linux/syscalls.h> | 38 | #include <linux/syscalls.h> |
| 39 | #include <linux/jiffies.h> | 39 | #include <linux/jiffies.h> |
| 40 | #include <linux/tracehook.h> | ||
| 40 | #include <linux/futex.h> | 41 | #include <linux/futex.h> |
| 41 | #include <linux/task_io_accounting_ops.h> | 42 | #include <linux/task_io_accounting_ops.h> |
| 42 | #include <linux/rcupdate.h> | 43 | #include <linux/rcupdate.h> |
| @@ -865,8 +866,7 @@ static void copy_flags(unsigned long clone_flags, struct task_struct *p) | |||
| 865 | 866 | ||
| 866 | new_flags &= ~PF_SUPERPRIV; | 867 | new_flags &= ~PF_SUPERPRIV; |
| 867 | new_flags |= PF_FORKNOEXEC; | 868 | new_flags |= PF_FORKNOEXEC; |
| 868 | if (!(clone_flags & CLONE_PTRACE)) | 869 | new_flags |= PF_STARTING; |
| 869 | p->ptrace = 0; | ||
| 870 | p->flags = new_flags; | 870 | p->flags = new_flags; |
| 871 | clear_freeze_flag(p); | 871 | clear_freeze_flag(p); |
| 872 | } | 872 | } |
| @@ -907,7 +907,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
| 907 | struct pt_regs *regs, | 907 | struct pt_regs *regs, |
| 908 | unsigned long stack_size, | 908 | unsigned long stack_size, |
| 909 | int __user *child_tidptr, | 909 | int __user *child_tidptr, |
| 910 | struct pid *pid) | 910 | struct pid *pid, |
| 911 | int trace) | ||
| 911 | { | 912 | { |
| 912 | int retval; | 913 | int retval; |
| 913 | struct task_struct *p; | 914 | struct task_struct *p; |
| @@ -1163,8 +1164,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
| 1163 | */ | 1164 | */ |
| 1164 | p->group_leader = p; | 1165 | p->group_leader = p; |
| 1165 | INIT_LIST_HEAD(&p->thread_group); | 1166 | INIT_LIST_HEAD(&p->thread_group); |
| 1166 | INIT_LIST_HEAD(&p->ptrace_entry); | ||
| 1167 | INIT_LIST_HEAD(&p->ptraced); | ||
| 1168 | 1167 | ||
| 1169 | /* Now that the task is set up, run cgroup callbacks if | 1168 | /* Now that the task is set up, run cgroup callbacks if |
| 1170 | * necessary. We need to run them before the task is visible | 1169 | * necessary. We need to run them before the task is visible |
| @@ -1195,7 +1194,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
| 1195 | p->real_parent = current->real_parent; | 1194 | p->real_parent = current->real_parent; |
| 1196 | else | 1195 | else |
| 1197 | p->real_parent = current; | 1196 | p->real_parent = current; |
| 1198 | p->parent = p->real_parent; | ||
| 1199 | 1197 | ||
| 1200 | spin_lock(¤t->sighand->siglock); | 1198 | spin_lock(¤t->sighand->siglock); |
| 1201 | 1199 | ||
| @@ -1237,8 +1235,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
| 1237 | 1235 | ||
| 1238 | if (likely(p->pid)) { | 1236 | if (likely(p->pid)) { |
| 1239 | list_add_tail(&p->sibling, &p->real_parent->children); | 1237 | list_add_tail(&p->sibling, &p->real_parent->children); |
| 1240 | if (unlikely(p->ptrace & PT_PTRACED)) | 1238 | tracehook_finish_clone(p, clone_flags, trace); |
| 1241 | __ptrace_link(p, current->parent); | ||
| 1242 | 1239 | ||
| 1243 | if (thread_group_leader(p)) { | 1240 | if (thread_group_leader(p)) { |
| 1244 | if (clone_flags & CLONE_NEWPID) | 1241 | if (clone_flags & CLONE_NEWPID) |
| @@ -1323,29 +1320,13 @@ struct task_struct * __cpuinit fork_idle(int cpu) | |||
| 1323 | struct pt_regs regs; | 1320 | struct pt_regs regs; |
| 1324 | 1321 | ||
| 1325 | task = copy_process(CLONE_VM, 0, idle_regs(®s), 0, NULL, | 1322 | task = copy_process(CLONE_VM, 0, idle_regs(®s), 0, NULL, |
| 1326 | &init_struct_pid); | 1323 | &init_struct_pid, 0); |
| 1327 | if (!IS_ERR(task)) | 1324 | if (!IS_ERR(task)) |
| 1328 | init_idle(task, cpu); | 1325 | init_idle(task, cpu); |
| 1329 | 1326 | ||
| 1330 | return task; | 1327 | return task; |
| 1331 | } | 1328 | } |
| 1332 | 1329 | ||
| 1333 | static int fork_traceflag(unsigned clone_flags) | ||
| 1334 | { | ||
| 1335 | if (clone_flags & CLONE_UNTRACED) | ||
| 1336 | return 0; | ||
| 1337 | else if (clone_flags & CLONE_VFORK) { | ||
| 1338 | if (current->ptrace & PT_TRACE_VFORK) | ||
| 1339 | return PTRACE_EVENT_VFORK; | ||
| 1340 | } else if ((clone_flags & CSIGNAL) != SIGCHLD) { | ||
| 1341 | if (current->ptrace & PT_TRACE_CLONE) | ||
| 1342 | return PTRACE_EVENT_CLONE; | ||
| 1343 | } else if (current->ptrace & PT_TRACE_FORK) | ||
| 1344 | return PTRACE_EVENT_FORK; | ||
| 1345 | |||
| 1346 | return 0; | ||
| 1347 | } | ||
| 1348 | |||
| 1349 | /* | 1330 | /* |
| 1350 | * Ok, this is the main fork-routine. | 1331 | * Ok, this is the main fork-routine. |
| 1351 | * | 1332 | * |
| @@ -1380,14 +1361,14 @@ long do_fork(unsigned long clone_flags, | |||
| 1380 | } | 1361 | } |
| 1381 | } | 1362 | } |
| 1382 | 1363 | ||
| 1383 | if (unlikely(current->ptrace)) { | 1364 | /* |
| 1384 | trace = fork_traceflag (clone_flags); | 1365 | * When called from kernel_thread, don't do user tracing stuff. |
| 1385 | if (trace) | 1366 | */ |
| 1386 | clone_flags |= CLONE_PTRACE; | 1367 | if (likely(user_mode(regs))) |
| 1387 | } | 1368 | trace = tracehook_prepare_clone(clone_flags); |
| 1388 | 1369 | ||
| 1389 | p = copy_process(clone_flags, stack_start, regs, stack_size, | 1370 | p = copy_process(clone_flags, stack_start, regs, stack_size, |
| 1390 | child_tidptr, NULL); | 1371 | child_tidptr, NULL, trace); |
| 1391 | /* | 1372 | /* |
| 1392 | * Do this prior waking up the new thread - the thread pointer | 1373 | * Do this prior waking up the new thread - the thread pointer |
| 1393 | * might get invalid after that point, if the thread exits quickly. | 1374 | * might get invalid after that point, if the thread exits quickly. |
| @@ -1405,32 +1386,35 @@ long do_fork(unsigned long clone_flags, | |||
| 1405 | init_completion(&vfork); | 1386 | init_completion(&vfork); |
| 1406 | } | 1387 | } |
| 1407 | 1388 | ||
| 1408 | if ((p->ptrace & PT_PTRACED) || (clone_flags & CLONE_STOPPED)) { | 1389 | tracehook_report_clone(trace, regs, clone_flags, nr, p); |
| 1390 | |||
| 1391 | /* | ||
| 1392 | * We set PF_STARTING at creation in case tracing wants to | ||
| 1393 | * use this to distinguish a fully live task from one that | ||
| 1394 | * hasn't gotten to tracehook_report_clone() yet. Now we | ||
| 1395 | * clear it and set the child going. | ||
| 1396 | */ | ||
| 1397 | p->flags &= ~PF_STARTING; | ||
| 1398 | |||
| 1399 | if (unlikely(clone_flags & CLONE_STOPPED)) { | ||
| 1409 | /* | 1400 | /* |
| 1410 | * We'll start up with an immediate SIGSTOP. | 1401 | * We'll start up with an immediate SIGSTOP. |
| 1411 | */ | 1402 | */ |
| 1412 | sigaddset(&p->pending.signal, SIGSTOP); | 1403 | sigaddset(&p->pending.signal, SIGSTOP); |
| 1413 | set_tsk_thread_flag(p, TIF_SIGPENDING); | 1404 | set_tsk_thread_flag(p, TIF_SIGPENDING); |
| 1414 | } | ||
| 1415 | |||
| 1416 | if (!(clone_flags & CLONE_STOPPED)) | ||
| 1417 | wake_up_new_task(p, clone_flags); | ||
| 1418 | else | ||
| 1419 | __set_task_state(p, TASK_STOPPED); | 1405 | __set_task_state(p, TASK_STOPPED); |
| 1420 | 1406 | } else { | |
| 1421 | if (unlikely (trace)) { | 1407 | wake_up_new_task(p, clone_flags); |
| 1422 | current->ptrace_message = nr; | ||
| 1423 | ptrace_notify ((trace << 8) | SIGTRAP); | ||
| 1424 | } | 1408 | } |
| 1425 | 1409 | ||
| 1410 | tracehook_report_clone_complete(trace, regs, | ||
| 1411 | clone_flags, nr, p); | ||
| 1412 | |||
| 1426 | if (clone_flags & CLONE_VFORK) { | 1413 | if (clone_flags & CLONE_VFORK) { |
| 1427 | freezer_do_not_count(); | 1414 | freezer_do_not_count(); |
| 1428 | wait_for_completion(&vfork); | 1415 | wait_for_completion(&vfork); |
| 1429 | freezer_count(); | 1416 | freezer_count(); |
| 1430 | if (unlikely (current->ptrace & PT_TRACE_VFORK_DONE)) { | 1417 | tracehook_report_vfork_done(p, nr); |
| 1431 | current->ptrace_message = nr; | ||
| 1432 | ptrace_notify ((PTRACE_EVENT_VFORK_DONE << 8) | SIGTRAP); | ||
| 1433 | } | ||
| 1434 | } | 1418 | } |
| 1435 | } else { | 1419 | } else { |
| 1436 | nr = PTR_ERR(p); | 1420 | nr = PTR_ERR(p); |
| @@ -1442,7 +1426,7 @@ long do_fork(unsigned long clone_flags, | |||
| 1442 | #define ARCH_MIN_MMSTRUCT_ALIGN 0 | 1426 | #define ARCH_MIN_MMSTRUCT_ALIGN 0 |
| 1443 | #endif | 1427 | #endif |
| 1444 | 1428 | ||
| 1445 | static void sighand_ctor(struct kmem_cache *cachep, void *data) | 1429 | static void sighand_ctor(void *data) |
| 1446 | { | 1430 | { |
| 1447 | struct sighand_struct *sighand = data; | 1431 | struct sighand_struct *sighand = data; |
| 1448 | 1432 | ||
