diff options
Diffstat (limited to 'fs/exec.c')
| -rw-r--r-- | fs/exec.c | 50 |
1 files changed, 32 insertions, 18 deletions
| @@ -195,7 +195,7 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | |||
| 195 | * to work from. | 195 | * to work from. |
| 196 | */ | 196 | */ |
| 197 | rlim = current->signal->rlim; | 197 | rlim = current->signal->rlim; |
| 198 | if (size > rlim[RLIMIT_STACK].rlim_cur / 4) { | 198 | if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur) / 4) { |
| 199 | put_page(page); | 199 | put_page(page); |
| 200 | return NULL; | 200 | return NULL; |
| 201 | } | 201 | } |
| @@ -246,6 +246,7 @@ static int __bprm_mm_init(struct linux_binprm *bprm) | |||
| 246 | vma->vm_start = vma->vm_end - PAGE_SIZE; | 246 | vma->vm_start = vma->vm_end - PAGE_SIZE; |
| 247 | vma->vm_flags = VM_STACK_FLAGS; | 247 | vma->vm_flags = VM_STACK_FLAGS; |
| 248 | vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); | 248 | vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
| 249 | INIT_LIST_HEAD(&vma->anon_vma_chain); | ||
| 249 | err = insert_vm_struct(mm, vma); | 250 | err = insert_vm_struct(mm, vma); |
| 250 | if (err) | 251 | if (err) |
| 251 | goto err; | 252 | goto err; |
| @@ -516,7 +517,8 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) | |||
| 516 | /* | 517 | /* |
| 517 | * cover the whole range: [new_start, old_end) | 518 | * cover the whole range: [new_start, old_end) |
| 518 | */ | 519 | */ |
| 519 | vma_adjust(vma, new_start, old_end, vma->vm_pgoff, NULL); | 520 | if (vma_adjust(vma, new_start, old_end, vma->vm_pgoff, NULL)) |
| 521 | return -ENOMEM; | ||
| 520 | 522 | ||
| 521 | /* | 523 | /* |
| 522 | * move the page tables downwards, on failure we rely on | 524 | * move the page tables downwards, on failure we rely on |
| @@ -547,15 +549,13 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) | |||
| 547 | tlb_finish_mmu(tlb, new_end, old_end); | 549 | tlb_finish_mmu(tlb, new_end, old_end); |
| 548 | 550 | ||
| 549 | /* | 551 | /* |
| 550 | * shrink the vma to just the new range. | 552 | * Shrink the vma to just the new range. Always succeeds. |
| 551 | */ | 553 | */ |
| 552 | vma_adjust(vma, new_start, new_end, vma->vm_pgoff, NULL); | 554 | vma_adjust(vma, new_start, new_end, vma->vm_pgoff, NULL); |
| 553 | 555 | ||
| 554 | return 0; | 556 | return 0; |
| 555 | } | 557 | } |
| 556 | 558 | ||
| 557 | #define EXTRA_STACK_VM_PAGES 20 /* random */ | ||
| 558 | |||
| 559 | /* | 559 | /* |
| 560 | * Finalizes the stack vm_area_struct. The flags and permissions are updated, | 560 | * Finalizes the stack vm_area_struct. The flags and permissions are updated, |
| 561 | * the stack is optionally relocated, and some extra space is added. | 561 | * the stack is optionally relocated, and some extra space is added. |
| @@ -577,7 +577,7 @@ int setup_arg_pages(struct linux_binprm *bprm, | |||
| 577 | 577 | ||
| 578 | #ifdef CONFIG_STACK_GROWSUP | 578 | #ifdef CONFIG_STACK_GROWSUP |
| 579 | /* Limit stack size to 1GB */ | 579 | /* Limit stack size to 1GB */ |
| 580 | stack_base = current->signal->rlim[RLIMIT_STACK].rlim_max; | 580 | stack_base = rlimit_max(RLIMIT_STACK); |
| 581 | if (stack_base > (1 << 30)) | 581 | if (stack_base > (1 << 30)) |
| 582 | stack_base = 1 << 30; | 582 | stack_base = 1 << 30; |
| 583 | 583 | ||
| @@ -630,7 +630,7 @@ int setup_arg_pages(struct linux_binprm *bprm, | |||
| 630 | goto out_unlock; | 630 | goto out_unlock; |
| 631 | } | 631 | } |
| 632 | 632 | ||
| 633 | stack_expand = EXTRA_STACK_VM_PAGES * PAGE_SIZE; | 633 | stack_expand = 131072UL; /* randomly 32*4k (or 2*64k) pages */ |
| 634 | stack_size = vma->vm_end - vma->vm_start; | 634 | stack_size = vma->vm_end - vma->vm_start; |
| 635 | /* | 635 | /* |
| 636 | * Align this down to a page boundary as expand_stack | 636 | * Align this down to a page boundary as expand_stack |
| @@ -718,6 +718,7 @@ static int exec_mmap(struct mm_struct *mm) | |||
| 718 | /* Notify parent that we're no longer interested in the old VM */ | 718 | /* Notify parent that we're no longer interested in the old VM */ |
| 719 | tsk = current; | 719 | tsk = current; |
| 720 | old_mm = current->mm; | 720 | old_mm = current->mm; |
| 721 | sync_mm_rss(tsk, old_mm); | ||
| 721 | mm_release(tsk, old_mm); | 722 | mm_release(tsk, old_mm); |
| 722 | 723 | ||
| 723 | if (old_mm) { | 724 | if (old_mm) { |
| @@ -1532,7 +1533,7 @@ static int format_corename(char *corename, long signr) | |||
| 1532 | /* core limit size */ | 1533 | /* core limit size */ |
| 1533 | case 'c': | 1534 | case 'c': |
| 1534 | rc = snprintf(out_ptr, out_end - out_ptr, | 1535 | rc = snprintf(out_ptr, out_end - out_ptr, |
| 1535 | "%lu", current->signal->rlim[RLIMIT_CORE].rlim_cur); | 1536 | "%lu", rlimit(RLIMIT_CORE)); |
| 1536 | if (rc > out_end - out_ptr) | 1537 | if (rc > out_end - out_ptr) |
| 1537 | goto out; | 1538 | goto out; |
| 1538 | out_ptr += rc; | 1539 | out_ptr += rc; |
| @@ -1560,12 +1561,13 @@ out: | |||
| 1560 | return ispipe; | 1561 | return ispipe; |
| 1561 | } | 1562 | } |
| 1562 | 1563 | ||
| 1563 | static int zap_process(struct task_struct *start) | 1564 | static int zap_process(struct task_struct *start, int exit_code) |
| 1564 | { | 1565 | { |
| 1565 | struct task_struct *t; | 1566 | struct task_struct *t; |
| 1566 | int nr = 0; | 1567 | int nr = 0; |
| 1567 | 1568 | ||
| 1568 | start->signal->flags = SIGNAL_GROUP_EXIT; | 1569 | start->signal->flags = SIGNAL_GROUP_EXIT; |
| 1570 | start->signal->group_exit_code = exit_code; | ||
| 1569 | start->signal->group_stop_count = 0; | 1571 | start->signal->group_stop_count = 0; |
| 1570 | 1572 | ||
| 1571 | t = start; | 1573 | t = start; |
| @@ -1590,8 +1592,7 @@ static inline int zap_threads(struct task_struct *tsk, struct mm_struct *mm, | |||
| 1590 | spin_lock_irq(&tsk->sighand->siglock); | 1592 | spin_lock_irq(&tsk->sighand->siglock); |
| 1591 | if (!signal_group_exit(tsk->signal)) { | 1593 | if (!signal_group_exit(tsk->signal)) { |
| 1592 | mm->core_state = core_state; | 1594 | mm->core_state = core_state; |
| 1593 | tsk->signal->group_exit_code = exit_code; | 1595 | nr = zap_process(tsk, exit_code); |
| 1594 | nr = zap_process(tsk); | ||
| 1595 | } | 1596 | } |
| 1596 | spin_unlock_irq(&tsk->sighand->siglock); | 1597 | spin_unlock_irq(&tsk->sighand->siglock); |
| 1597 | if (unlikely(nr < 0)) | 1598 | if (unlikely(nr < 0)) |
| @@ -1640,7 +1641,7 @@ static inline int zap_threads(struct task_struct *tsk, struct mm_struct *mm, | |||
| 1640 | if (p->mm) { | 1641 | if (p->mm) { |
| 1641 | if (unlikely(p->mm == mm)) { | 1642 | if (unlikely(p->mm == mm)) { |
| 1642 | lock_task_sighand(p, &flags); | 1643 | lock_task_sighand(p, &flags); |
| 1643 | nr += zap_process(p); | 1644 | nr += zap_process(p, exit_code); |
| 1644 | unlock_task_sighand(p, &flags); | 1645 | unlock_task_sighand(p, &flags); |
| 1645 | } | 1646 | } |
| 1646 | break; | 1647 | break; |
| @@ -1747,14 +1748,19 @@ void set_dumpable(struct mm_struct *mm, int value) | |||
| 1747 | } | 1748 | } |
| 1748 | } | 1749 | } |
| 1749 | 1750 | ||
| 1750 | int get_dumpable(struct mm_struct *mm) | 1751 | static int __get_dumpable(unsigned long mm_flags) |
| 1751 | { | 1752 | { |
| 1752 | int ret; | 1753 | int ret; |
| 1753 | 1754 | ||
| 1754 | ret = mm->flags & 0x3; | 1755 | ret = mm_flags & MMF_DUMPABLE_MASK; |
| 1755 | return (ret >= 2) ? 2 : ret; | 1756 | return (ret >= 2) ? 2 : ret; |
| 1756 | } | 1757 | } |
| 1757 | 1758 | ||
| 1759 | int get_dumpable(struct mm_struct *mm) | ||
| 1760 | { | ||
| 1761 | return __get_dumpable(mm->flags); | ||
| 1762 | } | ||
| 1763 | |||
| 1758 | static void wait_for_dump_helpers(struct file *file) | 1764 | static void wait_for_dump_helpers(struct file *file) |
| 1759 | { | 1765 | { |
| 1760 | struct pipe_inode_info *pipe; | 1766 | struct pipe_inode_info *pipe; |
| @@ -1797,7 +1803,13 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
| 1797 | struct coredump_params cprm = { | 1803 | struct coredump_params cprm = { |
| 1798 | .signr = signr, | 1804 | .signr = signr, |
| 1799 | .regs = regs, | 1805 | .regs = regs, |
| 1800 | .limit = current->signal->rlim[RLIMIT_CORE].rlim_cur, | 1806 | .limit = rlimit(RLIMIT_CORE), |
| 1807 | /* | ||
| 1808 | * We must use the same mm->flags while dumping core to avoid | ||
| 1809 | * inconsistency of bit flags, since this flag is not protected | ||
| 1810 | * by any locks. | ||
| 1811 | */ | ||
| 1812 | .mm_flags = mm->flags, | ||
| 1801 | }; | 1813 | }; |
| 1802 | 1814 | ||
| 1803 | audit_core_dumps(signr); | 1815 | audit_core_dumps(signr); |
| @@ -1816,7 +1828,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
| 1816 | /* | 1828 | /* |
| 1817 | * If another thread got here first, or we are not dumpable, bail out. | 1829 | * If another thread got here first, or we are not dumpable, bail out. |
| 1818 | */ | 1830 | */ |
| 1819 | if (mm->core_state || !get_dumpable(mm)) { | 1831 | if (mm->core_state || !__get_dumpable(cprm.mm_flags)) { |
| 1820 | up_write(&mm->mmap_sem); | 1832 | up_write(&mm->mmap_sem); |
| 1821 | put_cred(cred); | 1833 | put_cred(cred); |
| 1822 | goto fail; | 1834 | goto fail; |
| @@ -1827,7 +1839,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
| 1827 | * process nor do we know its entire history. We only know it | 1839 | * process nor do we know its entire history. We only know it |
| 1828 | * was tainted so we dump it as root in mode 2. | 1840 | * was tainted so we dump it as root in mode 2. |
| 1829 | */ | 1841 | */ |
| 1830 | if (get_dumpable(mm) == 2) { /* Setuid core dump mode */ | 1842 | if (__get_dumpable(cprm.mm_flags) == 2) { |
| 1843 | /* Setuid core dump mode */ | ||
| 1831 | flag = O_EXCL; /* Stop rewrite attacks */ | 1844 | flag = O_EXCL; /* Stop rewrite attacks */ |
| 1832 | cred->fsuid = 0; /* Dump root private */ | 1845 | cred->fsuid = 0; /* Dump root private */ |
| 1833 | } | 1846 | } |
| @@ -1923,8 +1936,9 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
| 1923 | /* | 1936 | /* |
| 1924 | * Dont allow local users get cute and trick others to coredump | 1937 | * Dont allow local users get cute and trick others to coredump |
| 1925 | * into their pre-created files: | 1938 | * into their pre-created files: |
| 1939 | * Note, this is not relevant for pipes | ||
| 1926 | */ | 1940 | */ |
| 1927 | if (inode->i_uid != current_fsuid()) | 1941 | if (!ispipe && (inode->i_uid != current_fsuid())) |
| 1928 | goto close_fail; | 1942 | goto close_fail; |
| 1929 | if (!cprm.file->f_op) | 1943 | if (!cprm.file->f_op) |
| 1930 | goto close_fail; | 1944 | goto close_fail; |
