diff options
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 147 |
1 files changed, 79 insertions, 68 deletions
@@ -666,8 +666,6 @@ static int de_thread(struct task_struct *tsk) | |||
666 | * and to assume its PID: | 666 | * and to assume its PID: |
667 | */ | 667 | */ |
668 | if (!thread_group_leader(current)) { | 668 | if (!thread_group_leader(current)) { |
669 | struct dentry *proc_dentry1, *proc_dentry2; | ||
670 | |||
671 | /* | 669 | /* |
672 | * Wait for the thread group leader to be a zombie. | 670 | * Wait for the thread group leader to be a zombie. |
673 | * It should already be zombie at this point, most | 671 | * It should already be zombie at this point, most |
@@ -689,10 +687,6 @@ static int de_thread(struct task_struct *tsk) | |||
689 | */ | 687 | */ |
690 | current->start_time = leader->start_time; | 688 | current->start_time = leader->start_time; |
691 | 689 | ||
692 | spin_lock(&leader->proc_lock); | ||
693 | spin_lock(¤t->proc_lock); | ||
694 | proc_dentry1 = proc_pid_unhash(current); | ||
695 | proc_dentry2 = proc_pid_unhash(leader); | ||
696 | write_lock_irq(&tasklist_lock); | 690 | write_lock_irq(&tasklist_lock); |
697 | 691 | ||
698 | BUG_ON(leader->tgid != current->tgid); | 692 | BUG_ON(leader->tgid != current->tgid); |
@@ -713,7 +707,7 @@ static int de_thread(struct task_struct *tsk) | |||
713 | attach_pid(current, PIDTYPE_PID, current->pid); | 707 | attach_pid(current, PIDTYPE_PID, current->pid); |
714 | attach_pid(current, PIDTYPE_PGID, current->signal->pgrp); | 708 | attach_pid(current, PIDTYPE_PGID, current->signal->pgrp); |
715 | attach_pid(current, PIDTYPE_SID, current->signal->session); | 709 | attach_pid(current, PIDTYPE_SID, current->signal->session); |
716 | list_add_tail_rcu(¤t->tasks, &init_task.tasks); | 710 | list_replace_rcu(&leader->tasks, ¤t->tasks); |
717 | 711 | ||
718 | current->group_leader = current; | 712 | current->group_leader = current; |
719 | leader->group_leader = current; | 713 | leader->group_leader = current; |
@@ -721,7 +715,6 @@ static int de_thread(struct task_struct *tsk) | |||
721 | /* Reduce leader to a thread */ | 715 | /* Reduce leader to a thread */ |
722 | detach_pid(leader, PIDTYPE_PGID); | 716 | detach_pid(leader, PIDTYPE_PGID); |
723 | detach_pid(leader, PIDTYPE_SID); | 717 | detach_pid(leader, PIDTYPE_SID); |
724 | list_del_init(&leader->tasks); | ||
725 | 718 | ||
726 | current->exit_signal = SIGCHLD; | 719 | current->exit_signal = SIGCHLD; |
727 | 720 | ||
@@ -729,10 +722,6 @@ static int de_thread(struct task_struct *tsk) | |||
729 | leader->exit_state = EXIT_DEAD; | 722 | leader->exit_state = EXIT_DEAD; |
730 | 723 | ||
731 | write_unlock_irq(&tasklist_lock); | 724 | write_unlock_irq(&tasklist_lock); |
732 | spin_unlock(&leader->proc_lock); | ||
733 | spin_unlock(¤t->proc_lock); | ||
734 | proc_pid_flush(proc_dentry1); | ||
735 | proc_pid_flush(proc_dentry2); | ||
736 | } | 725 | } |
737 | 726 | ||
738 | /* | 727 | /* |
@@ -1379,67 +1368,102 @@ static void format_corename(char *corename, const char *pattern, long signr) | |||
1379 | *out_ptr = 0; | 1368 | *out_ptr = 0; |
1380 | } | 1369 | } |
1381 | 1370 | ||
1382 | static void zap_threads (struct mm_struct *mm) | 1371 | static void zap_process(struct task_struct *start) |
1383 | { | 1372 | { |
1384 | struct task_struct *g, *p; | 1373 | struct task_struct *t; |
1385 | struct task_struct *tsk = current; | ||
1386 | struct completion *vfork_done = tsk->vfork_done; | ||
1387 | int traced = 0; | ||
1388 | 1374 | ||
1389 | /* | 1375 | start->signal->flags = SIGNAL_GROUP_EXIT; |
1390 | * Make sure nobody is waiting for us to release the VM, | 1376 | start->signal->group_stop_count = 0; |
1391 | * otherwise we can deadlock when we wait on each other | ||
1392 | */ | ||
1393 | if (vfork_done) { | ||
1394 | tsk->vfork_done = NULL; | ||
1395 | complete(vfork_done); | ||
1396 | } | ||
1397 | 1377 | ||
1398 | read_lock(&tasklist_lock); | 1378 | t = start; |
1399 | do_each_thread(g,p) | 1379 | do { |
1400 | if (mm == p->mm && p != tsk) { | 1380 | if (t != current && t->mm) { |
1401 | force_sig_specific(SIGKILL, p); | 1381 | t->mm->core_waiters++; |
1402 | mm->core_waiters++; | 1382 | sigaddset(&t->pending.signal, SIGKILL); |
1403 | if (unlikely(p->ptrace) && | 1383 | signal_wake_up(t, 1); |
1404 | unlikely(p->parent->mm == mm)) | ||
1405 | traced = 1; | ||
1406 | } | 1384 | } |
1407 | while_each_thread(g,p); | 1385 | } while ((t = next_thread(t)) != start); |
1386 | } | ||
1408 | 1387 | ||
1409 | read_unlock(&tasklist_lock); | 1388 | static inline int zap_threads(struct task_struct *tsk, struct mm_struct *mm, |
1389 | int exit_code) | ||
1390 | { | ||
1391 | struct task_struct *g, *p; | ||
1392 | unsigned long flags; | ||
1393 | int err = -EAGAIN; | ||
1394 | |||
1395 | spin_lock_irq(&tsk->sighand->siglock); | ||
1396 | if (!(tsk->signal->flags & SIGNAL_GROUP_EXIT)) { | ||
1397 | tsk->signal->group_exit_code = exit_code; | ||
1398 | zap_process(tsk); | ||
1399 | err = 0; | ||
1400 | } | ||
1401 | spin_unlock_irq(&tsk->sighand->siglock); | ||
1402 | if (err) | ||
1403 | return err; | ||
1410 | 1404 | ||
1411 | if (unlikely(traced)) { | 1405 | if (atomic_read(&mm->mm_users) == mm->core_waiters + 1) |
1412 | /* | 1406 | goto done; |
1413 | * We are zapping a thread and the thread it ptraces. | 1407 | |
1414 | * If the tracee went into a ptrace stop for exit tracing, | 1408 | rcu_read_lock(); |
1415 | * we could deadlock since the tracer is waiting for this | 1409 | for_each_process(g) { |
1416 | * coredump to finish. Detach them so they can both die. | 1410 | if (g == tsk->group_leader) |
1417 | */ | 1411 | continue; |
1418 | write_lock_irq(&tasklist_lock); | 1412 | |
1419 | do_each_thread(g,p) { | 1413 | p = g; |
1420 | if (mm == p->mm && p != tsk && | 1414 | do { |
1421 | p->ptrace && p->parent->mm == mm) { | 1415 | if (p->mm) { |
1422 | __ptrace_detach(p, 0); | 1416 | if (p->mm == mm) { |
1417 | /* | ||
1418 | * p->sighand can't disappear, but | ||
1419 | * may be changed by de_thread() | ||
1420 | */ | ||
1421 | lock_task_sighand(p, &flags); | ||
1422 | zap_process(p); | ||
1423 | unlock_task_sighand(p, &flags); | ||
1424 | } | ||
1425 | break; | ||
1423 | } | 1426 | } |
1424 | } while_each_thread(g,p); | 1427 | } while ((p = next_thread(p)) != g); |
1425 | write_unlock_irq(&tasklist_lock); | ||
1426 | } | 1428 | } |
1429 | rcu_read_unlock(); | ||
1430 | done: | ||
1431 | return mm->core_waiters; | ||
1427 | } | 1432 | } |
1428 | 1433 | ||
1429 | static void coredump_wait(struct mm_struct *mm) | 1434 | static int coredump_wait(int exit_code) |
1430 | { | 1435 | { |
1431 | DECLARE_COMPLETION(startup_done); | 1436 | struct task_struct *tsk = current; |
1437 | struct mm_struct *mm = tsk->mm; | ||
1438 | struct completion startup_done; | ||
1439 | struct completion *vfork_done; | ||
1432 | int core_waiters; | 1440 | int core_waiters; |
1433 | 1441 | ||
1442 | init_completion(&mm->core_done); | ||
1443 | init_completion(&startup_done); | ||
1434 | mm->core_startup_done = &startup_done; | 1444 | mm->core_startup_done = &startup_done; |
1435 | 1445 | ||
1436 | zap_threads(mm); | 1446 | core_waiters = zap_threads(tsk, mm, exit_code); |
1437 | core_waiters = mm->core_waiters; | ||
1438 | up_write(&mm->mmap_sem); | 1447 | up_write(&mm->mmap_sem); |
1439 | 1448 | ||
1449 | if (unlikely(core_waiters < 0)) | ||
1450 | goto fail; | ||
1451 | |||
1452 | /* | ||
1453 | * Make sure nobody is waiting for us to release the VM, | ||
1454 | * otherwise we can deadlock when we wait on each other | ||
1455 | */ | ||
1456 | vfork_done = tsk->vfork_done; | ||
1457 | if (vfork_done) { | ||
1458 | tsk->vfork_done = NULL; | ||
1459 | complete(vfork_done); | ||
1460 | } | ||
1461 | |||
1440 | if (core_waiters) | 1462 | if (core_waiters) |
1441 | wait_for_completion(&startup_done); | 1463 | wait_for_completion(&startup_done); |
1464 | fail: | ||
1442 | BUG_ON(mm->core_waiters); | 1465 | BUG_ON(mm->core_waiters); |
1466 | return core_waiters; | ||
1443 | } | 1467 | } |
1444 | 1468 | ||
1445 | int do_coredump(long signr, int exit_code, struct pt_regs * regs) | 1469 | int do_coredump(long signr, int exit_code, struct pt_regs * regs) |
@@ -1473,22 +1497,9 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) | |||
1473 | } | 1497 | } |
1474 | mm->dumpable = 0; | 1498 | mm->dumpable = 0; |
1475 | 1499 | ||
1476 | retval = -EAGAIN; | 1500 | retval = coredump_wait(exit_code); |
1477 | spin_lock_irq(¤t->sighand->siglock); | 1501 | if (retval < 0) |
1478 | if (!(current->signal->flags & SIGNAL_GROUP_EXIT)) { | ||
1479 | current->signal->flags = SIGNAL_GROUP_EXIT; | ||
1480 | current->signal->group_exit_code = exit_code; | ||
1481 | current->signal->group_stop_count = 0; | ||
1482 | retval = 0; | ||
1483 | } | ||
1484 | spin_unlock_irq(¤t->sighand->siglock); | ||
1485 | if (retval) { | ||
1486 | up_write(&mm->mmap_sem); | ||
1487 | goto fail; | 1502 | goto fail; |
1488 | } | ||
1489 | |||
1490 | init_completion(&mm->core_done); | ||
1491 | coredump_wait(mm); | ||
1492 | 1503 | ||
1493 | /* | 1504 | /* |
1494 | * Clear any false indication of pending signals that might | 1505 | * Clear any false indication of pending signals that might |