diff options
Diffstat (limited to 'fs/exec.c')
| -rw-r--r-- | fs/exec.c | 155 |
1 files changed, 97 insertions, 58 deletions
| @@ -25,32 +25,30 @@ | |||
| 25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
| 26 | #include <linux/file.h> | 26 | #include <linux/file.h> |
| 27 | #include <linux/fdtable.h> | 27 | #include <linux/fdtable.h> |
| 28 | #include <linux/mman.h> | 28 | #include <linux/mm.h> |
| 29 | #include <linux/stat.h> | 29 | #include <linux/stat.h> |
| 30 | #include <linux/fcntl.h> | 30 | #include <linux/fcntl.h> |
| 31 | #include <linux/smp_lock.h> | 31 | #include <linux/smp_lock.h> |
| 32 | #include <linux/swap.h> | ||
| 32 | #include <linux/string.h> | 33 | #include <linux/string.h> |
| 33 | #include <linux/init.h> | 34 | #include <linux/init.h> |
| 34 | #include <linux/pagemap.h> | ||
| 35 | #include <linux/highmem.h> | 35 | #include <linux/highmem.h> |
| 36 | #include <linux/spinlock.h> | 36 | #include <linux/spinlock.h> |
| 37 | #include <linux/key.h> | 37 | #include <linux/key.h> |
| 38 | #include <linux/personality.h> | 38 | #include <linux/personality.h> |
| 39 | #include <linux/binfmts.h> | 39 | #include <linux/binfmts.h> |
| 40 | #include <linux/swap.h> | ||
| 41 | #include <linux/utsname.h> | 40 | #include <linux/utsname.h> |
| 42 | #include <linux/pid_namespace.h> | 41 | #include <linux/pid_namespace.h> |
| 43 | #include <linux/module.h> | 42 | #include <linux/module.h> |
| 44 | #include <linux/namei.h> | 43 | #include <linux/namei.h> |
| 45 | #include <linux/proc_fs.h> | 44 | #include <linux/proc_fs.h> |
| 46 | #include <linux/ptrace.h> | ||
| 47 | #include <linux/mount.h> | 45 | #include <linux/mount.h> |
| 48 | #include <linux/security.h> | 46 | #include <linux/security.h> |
| 49 | #include <linux/syscalls.h> | 47 | #include <linux/syscalls.h> |
| 50 | #include <linux/rmap.h> | ||
| 51 | #include <linux/tsacct_kern.h> | 48 | #include <linux/tsacct_kern.h> |
| 52 | #include <linux/cn_proc.h> | 49 | #include <linux/cn_proc.h> |
| 53 | #include <linux/audit.h> | 50 | #include <linux/audit.h> |
| 51 | #include <linux/tracehook.h> | ||
| 54 | 52 | ||
| 55 | #include <asm/uaccess.h> | 53 | #include <asm/uaccess.h> |
| 56 | #include <asm/mmu_context.h> | 54 | #include <asm/mmu_context.h> |
| @@ -541,7 +539,7 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) | |||
| 541 | /* | 539 | /* |
| 542 | * when the old and new regions overlap clear from new_end. | 540 | * when the old and new regions overlap clear from new_end. |
| 543 | */ | 541 | */ |
| 544 | free_pgd_range(&tlb, new_end, old_end, new_end, | 542 | free_pgd_range(tlb, new_end, old_end, new_end, |
| 545 | vma->vm_next ? vma->vm_next->vm_start : 0); | 543 | vma->vm_next ? vma->vm_next->vm_start : 0); |
| 546 | } else { | 544 | } else { |
| 547 | /* | 545 | /* |
| @@ -550,7 +548,7 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) | |||
| 550 | * have constraints on va-space that make this illegal (IA64) - | 548 | * have constraints on va-space that make this illegal (IA64) - |
| 551 | * for the others its just a little faster. | 549 | * for the others its just a little faster. |
| 552 | */ | 550 | */ |
| 553 | free_pgd_range(&tlb, old_start, old_end, new_end, | 551 | free_pgd_range(tlb, old_start, old_end, new_end, |
| 554 | vma->vm_next ? vma->vm_next->vm_start : 0); | 552 | vma->vm_next ? vma->vm_next->vm_start : 0); |
| 555 | } | 553 | } |
| 556 | tlb_finish_mmu(tlb, new_end, old_end); | 554 | tlb_finish_mmu(tlb, new_end, old_end); |
| @@ -724,12 +722,10 @@ static int exec_mmap(struct mm_struct *mm) | |||
| 724 | * Make sure that if there is a core dump in progress | 722 | * Make sure that if there is a core dump in progress |
| 725 | * for the old mm, we get out and die instead of going | 723 | * for the old mm, we get out and die instead of going |
| 726 | * through with the exec. We must hold mmap_sem around | 724 | * through with the exec. We must hold mmap_sem around |
| 727 | * checking core_waiters and changing tsk->mm. The | 725 | * checking core_state and changing tsk->mm. |
| 728 | * core-inducing thread will increment core_waiters for | ||
| 729 | * each thread whose ->mm == old_mm. | ||
| 730 | */ | 726 | */ |
| 731 | down_read(&old_mm->mmap_sem); | 727 | down_read(&old_mm->mmap_sem); |
| 732 | if (unlikely(old_mm->core_waiters)) { | 728 | if (unlikely(old_mm->core_state)) { |
| 733 | up_read(&old_mm->mmap_sem); | 729 | up_read(&old_mm->mmap_sem); |
| 734 | return -EINTR; | 730 | return -EINTR; |
| 735 | } | 731 | } |
| @@ -1075,13 +1071,8 @@ EXPORT_SYMBOL(prepare_binprm); | |||
| 1075 | 1071 | ||
| 1076 | static int unsafe_exec(struct task_struct *p) | 1072 | static int unsafe_exec(struct task_struct *p) |
| 1077 | { | 1073 | { |
| 1078 | int unsafe = 0; | 1074 | int unsafe = tracehook_unsafe_exec(p); |
| 1079 | if (p->ptrace & PT_PTRACED) { | 1075 | |
| 1080 | if (p->ptrace & PT_PTRACE_CAP) | ||
| 1081 | unsafe |= LSM_UNSAFE_PTRACE_CAP; | ||
| 1082 | else | ||
| 1083 | unsafe |= LSM_UNSAFE_PTRACE; | ||
| 1084 | } | ||
| 1085 | if (atomic_read(&p->fs->count) > 1 || | 1076 | if (atomic_read(&p->fs->count) > 1 || |
| 1086 | atomic_read(&p->files->count) > 1 || | 1077 | atomic_read(&p->files->count) > 1 || |
| 1087 | atomic_read(&p->sighand->count) > 1) | 1078 | atomic_read(&p->sighand->count) > 1) |
| @@ -1218,6 +1209,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) | |||
| 1218 | read_unlock(&binfmt_lock); | 1209 | read_unlock(&binfmt_lock); |
| 1219 | retval = fn(bprm, regs); | 1210 | retval = fn(bprm, regs); |
| 1220 | if (retval >= 0) { | 1211 | if (retval >= 0) { |
| 1212 | tracehook_report_exec(fmt, bprm, regs); | ||
| 1221 | put_binfmt(fmt); | 1213 | put_binfmt(fmt); |
| 1222 | allow_write_access(bprm->file); | 1214 | allow_write_access(bprm->file); |
| 1223 | if (bprm->file) | 1215 | if (bprm->file) |
| @@ -1328,6 +1320,7 @@ int do_execve(char * filename, | |||
| 1328 | if (retval < 0) | 1320 | if (retval < 0) |
| 1329 | goto out; | 1321 | goto out; |
| 1330 | 1322 | ||
| 1323 | current->flags &= ~PF_KTHREAD; | ||
| 1331 | retval = search_binary_handler(bprm,regs); | 1324 | retval = search_binary_handler(bprm,regs); |
| 1332 | if (retval >= 0) { | 1325 | if (retval >= 0) { |
| 1333 | /* execve success */ | 1326 | /* execve success */ |
| @@ -1382,17 +1375,14 @@ EXPORT_SYMBOL(set_binfmt); | |||
| 1382 | * name into corename, which must have space for at least | 1375 | * name into corename, which must have space for at least |
| 1383 | * CORENAME_MAX_SIZE bytes plus one byte for the zero terminator. | 1376 | * CORENAME_MAX_SIZE bytes plus one byte for the zero terminator. |
| 1384 | */ | 1377 | */ |
| 1385 | static int format_corename(char *corename, const char *pattern, long signr) | 1378 | static int format_corename(char *corename, int nr_threads, long signr) |
| 1386 | { | 1379 | { |
| 1387 | const char *pat_ptr = pattern; | 1380 | const char *pat_ptr = core_pattern; |
| 1381 | int ispipe = (*pat_ptr == '|'); | ||
| 1388 | char *out_ptr = corename; | 1382 | char *out_ptr = corename; |
| 1389 | char *const out_end = corename + CORENAME_MAX_SIZE; | 1383 | char *const out_end = corename + CORENAME_MAX_SIZE; |
| 1390 | int rc; | 1384 | int rc; |
| 1391 | int pid_in_pattern = 0; | 1385 | int pid_in_pattern = 0; |
| 1392 | int ispipe = 0; | ||
| 1393 | |||
| 1394 | if (*pattern == '|') | ||
| 1395 | ispipe = 1; | ||
| 1396 | 1386 | ||
| 1397 | /* Repeat as long as we have more pattern to process and more output | 1387 | /* Repeat as long as we have more pattern to process and more output |
| 1398 | space */ | 1388 | space */ |
| @@ -1493,7 +1483,7 @@ static int format_corename(char *corename, const char *pattern, long signr) | |||
| 1493 | * and core_uses_pid is set, then .%pid will be appended to | 1483 | * and core_uses_pid is set, then .%pid will be appended to |
| 1494 | * the filename. Do not do this for piped commands. */ | 1484 | * the filename. Do not do this for piped commands. */ |
| 1495 | if (!ispipe && !pid_in_pattern | 1485 | if (!ispipe && !pid_in_pattern |
| 1496 | && (core_uses_pid || atomic_read(¤t->mm->mm_users) != 1)) { | 1486 | && (core_uses_pid || nr_threads)) { |
| 1497 | rc = snprintf(out_ptr, out_end - out_ptr, | 1487 | rc = snprintf(out_ptr, out_end - out_ptr, |
| 1498 | ".%d", task_tgid_vnr(current)); | 1488 | ".%d", task_tgid_vnr(current)); |
| 1499 | if (rc > out_end - out_ptr) | 1489 | if (rc > out_end - out_ptr) |
| @@ -1505,9 +1495,10 @@ out: | |||
| 1505 | return ispipe; | 1495 | return ispipe; |
| 1506 | } | 1496 | } |
| 1507 | 1497 | ||
| 1508 | static void zap_process(struct task_struct *start) | 1498 | static int zap_process(struct task_struct *start) |
| 1509 | { | 1499 | { |
| 1510 | struct task_struct *t; | 1500 | struct task_struct *t; |
| 1501 | int nr = 0; | ||
| 1511 | 1502 | ||
| 1512 | start->signal->flags = SIGNAL_GROUP_EXIT; | 1503 | start->signal->flags = SIGNAL_GROUP_EXIT; |
| 1513 | start->signal->group_stop_count = 0; | 1504 | start->signal->group_stop_count = 0; |
| @@ -1515,72 +1506,99 @@ static void zap_process(struct task_struct *start) | |||
| 1515 | t = start; | 1506 | t = start; |
| 1516 | do { | 1507 | do { |
| 1517 | if (t != current && t->mm) { | 1508 | if (t != current && t->mm) { |
| 1518 | t->mm->core_waiters++; | ||
| 1519 | sigaddset(&t->pending.signal, SIGKILL); | 1509 | sigaddset(&t->pending.signal, SIGKILL); |
| 1520 | signal_wake_up(t, 1); | 1510 | signal_wake_up(t, 1); |
| 1511 | nr++; | ||
| 1521 | } | 1512 | } |
| 1522 | } while ((t = next_thread(t)) != start); | 1513 | } while_each_thread(start, t); |
| 1514 | |||
| 1515 | return nr; | ||
| 1523 | } | 1516 | } |
| 1524 | 1517 | ||
| 1525 | static inline int zap_threads(struct task_struct *tsk, struct mm_struct *mm, | 1518 | static inline int zap_threads(struct task_struct *tsk, struct mm_struct *mm, |
| 1526 | int exit_code) | 1519 | struct core_state *core_state, int exit_code) |
| 1527 | { | 1520 | { |
| 1528 | struct task_struct *g, *p; | 1521 | struct task_struct *g, *p; |
| 1529 | unsigned long flags; | 1522 | unsigned long flags; |
| 1530 | int err = -EAGAIN; | 1523 | int nr = -EAGAIN; |
| 1531 | 1524 | ||
| 1532 | spin_lock_irq(&tsk->sighand->siglock); | 1525 | spin_lock_irq(&tsk->sighand->siglock); |
| 1533 | if (!signal_group_exit(tsk->signal)) { | 1526 | if (!signal_group_exit(tsk->signal)) { |
| 1527 | mm->core_state = core_state; | ||
| 1534 | tsk->signal->group_exit_code = exit_code; | 1528 | tsk->signal->group_exit_code = exit_code; |
| 1535 | zap_process(tsk); | 1529 | nr = zap_process(tsk); |
| 1536 | err = 0; | ||
| 1537 | } | 1530 | } |
| 1538 | spin_unlock_irq(&tsk->sighand->siglock); | 1531 | spin_unlock_irq(&tsk->sighand->siglock); |
| 1539 | if (err) | 1532 | if (unlikely(nr < 0)) |
| 1540 | return err; | 1533 | return nr; |
| 1541 | 1534 | ||
| 1542 | if (atomic_read(&mm->mm_users) == mm->core_waiters + 1) | 1535 | if (atomic_read(&mm->mm_users) == nr + 1) |
| 1543 | goto done; | 1536 | goto done; |
| 1544 | 1537 | /* | |
| 1538 | * We should find and kill all tasks which use this mm, and we should | ||
| 1539 | * count them correctly into ->nr_threads. We don't take tasklist | ||
| 1540 | * lock, but this is safe wrt: | ||
| 1541 | * | ||
| 1542 | * fork: | ||
| 1543 | * None of sub-threads can fork after zap_process(leader). All | ||
| 1544 | * processes which were created before this point should be | ||
| 1545 | * visible to zap_threads() because copy_process() adds the new | ||
| 1546 | * process to the tail of init_task.tasks list, and lock/unlock | ||
| 1547 | * of ->siglock provides a memory barrier. | ||
| 1548 | * | ||
| 1549 | * do_exit: | ||
| 1550 | * The caller holds mm->mmap_sem. This means that the task which | ||
| 1551 | * uses this mm can't pass exit_mm(), so it can't exit or clear | ||
| 1552 | * its ->mm. | ||
| 1553 | * | ||
| 1554 | * de_thread: | ||
| 1555 | * It does list_replace_rcu(&leader->tasks, ¤t->tasks), | ||
| 1556 | * we must see either old or new leader, this does not matter. | ||
| 1557 | * However, it can change p->sighand, so lock_task_sighand(p) | ||
| 1558 | * must be used. Since p->mm != NULL and we hold ->mmap_sem | ||
| 1559 | * it can't fail. | ||
| 1560 | * | ||
| 1561 | * Note also that "g" can be the old leader with ->mm == NULL | ||
| 1562 | * and already unhashed and thus removed from ->thread_group. | ||
| 1563 | * This is OK, __unhash_process()->list_del_rcu() does not | ||
| 1564 | * clear the ->next pointer, we will find the new leader via | ||
| 1565 | * next_thread(). | ||
| 1566 | */ | ||
| 1545 | rcu_read_lock(); | 1567 | rcu_read_lock(); |
| 1546 | for_each_process(g) { | 1568 | for_each_process(g) { |
| 1547 | if (g == tsk->group_leader) | 1569 | if (g == tsk->group_leader) |
| 1548 | continue; | 1570 | continue; |
| 1549 | 1571 | if (g->flags & PF_KTHREAD) | |
| 1572 | continue; | ||
| 1550 | p = g; | 1573 | p = g; |
| 1551 | do { | 1574 | do { |
| 1552 | if (p->mm) { | 1575 | if (p->mm) { |
| 1553 | if (p->mm == mm) { | 1576 | if (unlikely(p->mm == mm)) { |
| 1554 | /* | ||
| 1555 | * p->sighand can't disappear, but | ||
| 1556 | * may be changed by de_thread() | ||
| 1557 | */ | ||
| 1558 | lock_task_sighand(p, &flags); | 1577 | lock_task_sighand(p, &flags); |
| 1559 | zap_process(p); | 1578 | nr += zap_process(p); |
| 1560 | unlock_task_sighand(p, &flags); | 1579 | unlock_task_sighand(p, &flags); |
| 1561 | } | 1580 | } |
| 1562 | break; | 1581 | break; |
| 1563 | } | 1582 | } |
| 1564 | } while ((p = next_thread(p)) != g); | 1583 | } while_each_thread(g, p); |
| 1565 | } | 1584 | } |
| 1566 | rcu_read_unlock(); | 1585 | rcu_read_unlock(); |
| 1567 | done: | 1586 | done: |
| 1568 | return mm->core_waiters; | 1587 | atomic_set(&core_state->nr_threads, nr); |
| 1588 | return nr; | ||
| 1569 | } | 1589 | } |
| 1570 | 1590 | ||
| 1571 | static int coredump_wait(int exit_code) | 1591 | static int coredump_wait(int exit_code, struct core_state *core_state) |
| 1572 | { | 1592 | { |
| 1573 | struct task_struct *tsk = current; | 1593 | struct task_struct *tsk = current; |
| 1574 | struct mm_struct *mm = tsk->mm; | 1594 | struct mm_struct *mm = tsk->mm; |
| 1575 | struct completion startup_done; | ||
| 1576 | struct completion *vfork_done; | 1595 | struct completion *vfork_done; |
| 1577 | int core_waiters; | 1596 | int core_waiters; |
| 1578 | 1597 | ||
| 1579 | init_completion(&mm->core_done); | 1598 | init_completion(&core_state->startup); |
| 1580 | init_completion(&startup_done); | 1599 | core_state->dumper.task = tsk; |
| 1581 | mm->core_startup_done = &startup_done; | 1600 | core_state->dumper.next = NULL; |
| 1582 | 1601 | core_waiters = zap_threads(tsk, mm, core_state, exit_code); | |
| 1583 | core_waiters = zap_threads(tsk, mm, exit_code); | ||
| 1584 | up_write(&mm->mmap_sem); | 1602 | up_write(&mm->mmap_sem); |
| 1585 | 1603 | ||
| 1586 | if (unlikely(core_waiters < 0)) | 1604 | if (unlikely(core_waiters < 0)) |
| @@ -1597,12 +1615,32 @@ static int coredump_wait(int exit_code) | |||
| 1597 | } | 1615 | } |
| 1598 | 1616 | ||
| 1599 | if (core_waiters) | 1617 | if (core_waiters) |
| 1600 | wait_for_completion(&startup_done); | 1618 | wait_for_completion(&core_state->startup); |
| 1601 | fail: | 1619 | fail: |
| 1602 | BUG_ON(mm->core_waiters); | ||
| 1603 | return core_waiters; | 1620 | return core_waiters; |
| 1604 | } | 1621 | } |
| 1605 | 1622 | ||
| 1623 | static void coredump_finish(struct mm_struct *mm) | ||
| 1624 | { | ||
| 1625 | struct core_thread *curr, *next; | ||
| 1626 | struct task_struct *task; | ||
| 1627 | |||
| 1628 | next = mm->core_state->dumper.next; | ||
| 1629 | while ((curr = next) != NULL) { | ||
| 1630 | next = curr->next; | ||
| 1631 | task = curr->task; | ||
| 1632 | /* | ||
| 1633 | * see exit_mm(), curr->task must not see | ||
| 1634 | * ->task == NULL before we read ->next. | ||
| 1635 | */ | ||
| 1636 | smp_mb(); | ||
| 1637 | curr->task = NULL; | ||
| 1638 | wake_up_process(task); | ||
| 1639 | } | ||
| 1640 | |||
| 1641 | mm->core_state = NULL; | ||
| 1642 | } | ||
| 1643 | |||
| 1606 | /* | 1644 | /* |
| 1607 | * set_dumpable converts traditional three-value dumpable to two flags and | 1645 | * set_dumpable converts traditional three-value dumpable to two flags and |
| 1608 | * stores them into mm->flags. It modifies lower two bits of mm->flags, but | 1646 | * stores them into mm->flags. It modifies lower two bits of mm->flags, but |
| @@ -1654,6 +1692,7 @@ int get_dumpable(struct mm_struct *mm) | |||
| 1654 | 1692 | ||
| 1655 | int do_coredump(long signr, int exit_code, struct pt_regs * regs) | 1693 | int do_coredump(long signr, int exit_code, struct pt_regs * regs) |
| 1656 | { | 1694 | { |
| 1695 | struct core_state core_state; | ||
| 1657 | char corename[CORENAME_MAX_SIZE + 1]; | 1696 | char corename[CORENAME_MAX_SIZE + 1]; |
| 1658 | struct mm_struct *mm = current->mm; | 1697 | struct mm_struct *mm = current->mm; |
| 1659 | struct linux_binfmt * binfmt; | 1698 | struct linux_binfmt * binfmt; |
| @@ -1677,7 +1716,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) | |||
| 1677 | /* | 1716 | /* |
| 1678 | * If another thread got here first, or we are not dumpable, bail out. | 1717 | * If another thread got here first, or we are not dumpable, bail out. |
| 1679 | */ | 1718 | */ |
| 1680 | if (mm->core_waiters || !get_dumpable(mm)) { | 1719 | if (mm->core_state || !get_dumpable(mm)) { |
| 1681 | up_write(&mm->mmap_sem); | 1720 | up_write(&mm->mmap_sem); |
| 1682 | goto fail; | 1721 | goto fail; |
| 1683 | } | 1722 | } |
| @@ -1692,7 +1731,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) | |||
| 1692 | current->fsuid = 0; /* Dump root private */ | 1731 | current->fsuid = 0; /* Dump root private */ |
| 1693 | } | 1732 | } |
| 1694 | 1733 | ||
| 1695 | retval = coredump_wait(exit_code); | 1734 | retval = coredump_wait(exit_code, &core_state); |
| 1696 | if (retval < 0) | 1735 | if (retval < 0) |
| 1697 | goto fail; | 1736 | goto fail; |
| 1698 | 1737 | ||
| @@ -1707,7 +1746,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) | |||
| 1707 | * uses lock_kernel() | 1746 | * uses lock_kernel() |
| 1708 | */ | 1747 | */ |
| 1709 | lock_kernel(); | 1748 | lock_kernel(); |
| 1710 | ispipe = format_corename(corename, core_pattern, signr); | 1749 | ispipe = format_corename(corename, retval, signr); |
| 1711 | unlock_kernel(); | 1750 | unlock_kernel(); |
| 1712 | /* | 1751 | /* |
| 1713 | * Don't bother to check the RLIMIT_CORE value if core_pattern points | 1752 | * Don't bother to check the RLIMIT_CORE value if core_pattern points |
| @@ -1786,7 +1825,7 @@ fail_unlock: | |||
| 1786 | argv_free(helper_argv); | 1825 | argv_free(helper_argv); |
| 1787 | 1826 | ||
| 1788 | current->fsuid = fsuid; | 1827 | current->fsuid = fsuid; |
| 1789 | complete_all(&mm->core_done); | 1828 | coredump_finish(mm); |
| 1790 | fail: | 1829 | fail: |
| 1791 | return retval; | 1830 | return retval; |
| 1792 | } | 1831 | } |
