diff options
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 185 |
1 files changed, 148 insertions, 37 deletions
@@ -42,7 +42,6 @@ | |||
42 | #include <linux/pid_namespace.h> | 42 | #include <linux/pid_namespace.h> |
43 | #include <linux/module.h> | 43 | #include <linux/module.h> |
44 | #include <linux/namei.h> | 44 | #include <linux/namei.h> |
45 | #include <linux/proc_fs.h> | ||
46 | #include <linux/mount.h> | 45 | #include <linux/mount.h> |
47 | #include <linux/security.h> | 46 | #include <linux/security.h> |
48 | #include <linux/syscalls.h> | 47 | #include <linux/syscalls.h> |
@@ -55,6 +54,7 @@ | |||
55 | #include <linux/fs_struct.h> | 54 | #include <linux/fs_struct.h> |
56 | #include <linux/pipe_fs_i.h> | 55 | #include <linux/pipe_fs_i.h> |
57 | #include <linux/oom.h> | 56 | #include <linux/oom.h> |
57 | #include <linux/compat.h> | ||
58 | 58 | ||
59 | #include <asm/uaccess.h> | 59 | #include <asm/uaccess.h> |
60 | #include <asm/mmu_context.h> | 60 | #include <asm/mmu_context.h> |
@@ -166,8 +166,13 @@ out: | |||
166 | } | 166 | } |
167 | 167 | ||
168 | #ifdef CONFIG_MMU | 168 | #ifdef CONFIG_MMU |
169 | 169 | /* | |
170 | void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) | 170 | * The nascent bprm->mm is not visible until exec_mmap() but it can |
171 | * use a lot of memory, account these pages in current->mm temporary | ||
172 | * for oom_badness()->get_mm_rss(). Once exec succeeds or fails, we | ||
173 | * change the counter back via acct_arg_size(0). | ||
174 | */ | ||
175 | static void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) | ||
171 | { | 176 | { |
172 | struct mm_struct *mm = current->mm; | 177 | struct mm_struct *mm = current->mm; |
173 | long diff = (long)(pages - bprm->vma_pages); | 178 | long diff = (long)(pages - bprm->vma_pages); |
@@ -186,7 +191,7 @@ void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) | |||
186 | #endif | 191 | #endif |
187 | } | 192 | } |
188 | 193 | ||
189 | struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | 194 | static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, |
190 | int write) | 195 | int write) |
191 | { | 196 | { |
192 | struct page *page; | 197 | struct page *page; |
@@ -194,7 +199,7 @@ struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | |||
194 | 199 | ||
195 | #ifdef CONFIG_STACK_GROWSUP | 200 | #ifdef CONFIG_STACK_GROWSUP |
196 | if (write) { | 201 | if (write) { |
197 | ret = expand_stack_downwards(bprm->vma, pos); | 202 | ret = expand_downwards(bprm->vma, pos); |
198 | if (ret < 0) | 203 | if (ret < 0) |
199 | return NULL; | 204 | return NULL; |
200 | } | 205 | } |
@@ -305,11 +310,11 @@ static bool valid_arg_len(struct linux_binprm *bprm, long len) | |||
305 | 310 | ||
306 | #else | 311 | #else |
307 | 312 | ||
308 | void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) | 313 | static inline void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) |
309 | { | 314 | { |
310 | } | 315 | } |
311 | 316 | ||
312 | struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | 317 | static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, |
313 | int write) | 318 | int write) |
314 | { | 319 | { |
315 | struct page *page; | 320 | struct page *page; |
@@ -398,22 +403,56 @@ err: | |||
398 | return err; | 403 | return err; |
399 | } | 404 | } |
400 | 405 | ||
406 | struct user_arg_ptr { | ||
407 | #ifdef CONFIG_COMPAT | ||
408 | bool is_compat; | ||
409 | #endif | ||
410 | union { | ||
411 | const char __user *const __user *native; | ||
412 | #ifdef CONFIG_COMPAT | ||
413 | compat_uptr_t __user *compat; | ||
414 | #endif | ||
415 | } ptr; | ||
416 | }; | ||
417 | |||
418 | static const char __user *get_user_arg_ptr(struct user_arg_ptr argv, int nr) | ||
419 | { | ||
420 | const char __user *native; | ||
421 | |||
422 | #ifdef CONFIG_COMPAT | ||
423 | if (unlikely(argv.is_compat)) { | ||
424 | compat_uptr_t compat; | ||
425 | |||
426 | if (get_user(compat, argv.ptr.compat + nr)) | ||
427 | return ERR_PTR(-EFAULT); | ||
428 | |||
429 | return compat_ptr(compat); | ||
430 | } | ||
431 | #endif | ||
432 | |||
433 | if (get_user(native, argv.ptr.native + nr)) | ||
434 | return ERR_PTR(-EFAULT); | ||
435 | |||
436 | return native; | ||
437 | } | ||
438 | |||
401 | /* | 439 | /* |
402 | * count() counts the number of strings in array ARGV. | 440 | * count() counts the number of strings in array ARGV. |
403 | */ | 441 | */ |
404 | static int count(const char __user * const __user * argv, int max) | 442 | static int count(struct user_arg_ptr argv, int max) |
405 | { | 443 | { |
406 | int i = 0; | 444 | int i = 0; |
407 | 445 | ||
408 | if (argv != NULL) { | 446 | if (argv.ptr.native != NULL) { |
409 | for (;;) { | 447 | for (;;) { |
410 | const char __user * p; | 448 | const char __user *p = get_user_arg_ptr(argv, i); |
411 | 449 | ||
412 | if (get_user(p, argv)) | ||
413 | return -EFAULT; | ||
414 | if (!p) | 450 | if (!p) |
415 | break; | 451 | break; |
416 | argv++; | 452 | |
453 | if (IS_ERR(p)) | ||
454 | return -EFAULT; | ||
455 | |||
417 | if (i++ >= max) | 456 | if (i++ >= max) |
418 | return -E2BIG; | 457 | return -E2BIG; |
419 | 458 | ||
@@ -430,7 +469,7 @@ static int count(const char __user * const __user * argv, int max) | |||
430 | * processes's memory to the new process's stack. The call to get_user_pages() | 469 | * processes's memory to the new process's stack. The call to get_user_pages() |
431 | * ensures the destination page is created and not swapped out. | 470 | * ensures the destination page is created and not swapped out. |
432 | */ | 471 | */ |
433 | static int copy_strings(int argc, const char __user *const __user *argv, | 472 | static int copy_strings(int argc, struct user_arg_ptr argv, |
434 | struct linux_binprm *bprm) | 473 | struct linux_binprm *bprm) |
435 | { | 474 | { |
436 | struct page *kmapped_page = NULL; | 475 | struct page *kmapped_page = NULL; |
@@ -443,16 +482,18 @@ static int copy_strings(int argc, const char __user *const __user *argv, | |||
443 | int len; | 482 | int len; |
444 | unsigned long pos; | 483 | unsigned long pos; |
445 | 484 | ||
446 | if (get_user(str, argv+argc) || | 485 | ret = -EFAULT; |
447 | !(len = strnlen_user(str, MAX_ARG_STRLEN))) { | 486 | str = get_user_arg_ptr(argv, argc); |
448 | ret = -EFAULT; | 487 | if (IS_ERR(str)) |
449 | goto out; | 488 | goto out; |
450 | } | ||
451 | 489 | ||
452 | if (!valid_arg_len(bprm, len)) { | 490 | len = strnlen_user(str, MAX_ARG_STRLEN); |
453 | ret = -E2BIG; | 491 | if (!len) |
492 | goto out; | ||
493 | |||
494 | ret = -E2BIG; | ||
495 | if (!valid_arg_len(bprm, len)) | ||
454 | goto out; | 496 | goto out; |
455 | } | ||
456 | 497 | ||
457 | /* We're going to work our way backwords. */ | 498 | /* We're going to work our way backwords. */ |
458 | pos = bprm->p; | 499 | pos = bprm->p; |
@@ -519,14 +560,19 @@ out: | |||
519 | /* | 560 | /* |
520 | * Like copy_strings, but get argv and its values from kernel memory. | 561 | * Like copy_strings, but get argv and its values from kernel memory. |
521 | */ | 562 | */ |
522 | int copy_strings_kernel(int argc, const char *const *argv, | 563 | int copy_strings_kernel(int argc, const char *const *__argv, |
523 | struct linux_binprm *bprm) | 564 | struct linux_binprm *bprm) |
524 | { | 565 | { |
525 | int r; | 566 | int r; |
526 | mm_segment_t oldfs = get_fs(); | 567 | mm_segment_t oldfs = get_fs(); |
568 | struct user_arg_ptr argv = { | ||
569 | .ptr.native = (const char __user *const __user *)__argv, | ||
570 | }; | ||
571 | |||
527 | set_fs(KERNEL_DS); | 572 | set_fs(KERNEL_DS); |
528 | r = copy_strings(argc, (const char __user *const __user *)argv, bprm); | 573 | r = copy_strings(argc, argv, bprm); |
529 | set_fs(oldfs); | 574 | set_fs(oldfs); |
575 | |||
530 | return r; | 576 | return r; |
531 | } | 577 | } |
532 | EXPORT_SYMBOL(copy_strings_kernel); | 578 | EXPORT_SYMBOL(copy_strings_kernel); |
@@ -553,7 +599,7 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) | |||
553 | unsigned long length = old_end - old_start; | 599 | unsigned long length = old_end - old_start; |
554 | unsigned long new_start = old_start - shift; | 600 | unsigned long new_start = old_start - shift; |
555 | unsigned long new_end = old_end - shift; | 601 | unsigned long new_end = old_end - shift; |
556 | struct mmu_gather *tlb; | 602 | struct mmu_gather tlb; |
557 | 603 | ||
558 | BUG_ON(new_start > new_end); | 604 | BUG_ON(new_start > new_end); |
559 | 605 | ||
@@ -579,12 +625,12 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) | |||
579 | return -ENOMEM; | 625 | return -ENOMEM; |
580 | 626 | ||
581 | lru_add_drain(); | 627 | lru_add_drain(); |
582 | tlb = tlb_gather_mmu(mm, 0); | 628 | tlb_gather_mmu(&tlb, mm, 0); |
583 | if (new_end > old_start) { | 629 | if (new_end > old_start) { |
584 | /* | 630 | /* |
585 | * when the old and new regions overlap clear from new_end. | 631 | * when the old and new regions overlap clear from new_end. |
586 | */ | 632 | */ |
587 | free_pgd_range(tlb, new_end, old_end, new_end, | 633 | free_pgd_range(&tlb, new_end, old_end, new_end, |
588 | vma->vm_next ? vma->vm_next->vm_start : 0); | 634 | vma->vm_next ? vma->vm_next->vm_start : 0); |
589 | } else { | 635 | } else { |
590 | /* | 636 | /* |
@@ -593,10 +639,10 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) | |||
593 | * have constraints on va-space that make this illegal (IA64) - | 639 | * have constraints on va-space that make this illegal (IA64) - |
594 | * for the others its just a little faster. | 640 | * for the others its just a little faster. |
595 | */ | 641 | */ |
596 | free_pgd_range(tlb, old_start, old_end, new_end, | 642 | free_pgd_range(&tlb, old_start, old_end, new_end, |
597 | vma->vm_next ? vma->vm_next->vm_start : 0); | 643 | vma->vm_next ? vma->vm_next->vm_start : 0); |
598 | } | 644 | } |
599 | tlb_finish_mmu(tlb, new_end, old_end); | 645 | tlb_finish_mmu(&tlb, new_end, old_end); |
600 | 646 | ||
601 | /* | 647 | /* |
602 | * Shrink the vma to just the new range. Always succeeds. | 648 | * Shrink the vma to just the new range. Always succeeds. |
@@ -1004,6 +1050,7 @@ char *get_task_comm(char *buf, struct task_struct *tsk) | |||
1004 | task_unlock(tsk); | 1050 | task_unlock(tsk); |
1005 | return buf; | 1051 | return buf; |
1006 | } | 1052 | } |
1053 | EXPORT_SYMBOL_GPL(get_task_comm); | ||
1007 | 1054 | ||
1008 | void set_task_comm(struct task_struct *tsk, char *buf) | 1055 | void set_task_comm(struct task_struct *tsk, char *buf) |
1009 | { | 1056 | { |
@@ -1046,6 +1093,7 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
1046 | 1093 | ||
1047 | bprm->mm = NULL; /* We're using it now */ | 1094 | bprm->mm = NULL; /* We're using it now */ |
1048 | 1095 | ||
1096 | set_fs(USER_DS); | ||
1049 | current->flags &= ~(PF_RANDOMIZE | PF_KTHREAD); | 1097 | current->flags &= ~(PF_RANDOMIZE | PF_KTHREAD); |
1050 | flush_thread(); | 1098 | flush_thread(); |
1051 | current->personality &= ~bprm->per_clear; | 1099 | current->personality &= ~bprm->per_clear; |
@@ -1310,10 +1358,6 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) | |||
1310 | if (retval) | 1358 | if (retval) |
1311 | return retval; | 1359 | return retval; |
1312 | 1360 | ||
1313 | /* kernel module loader fixup */ | ||
1314 | /* so we don't try to load run modprobe in kernel space. */ | ||
1315 | set_fs(USER_DS); | ||
1316 | |||
1317 | retval = audit_bprm(bprm); | 1361 | retval = audit_bprm(bprm); |
1318 | if (retval) | 1362 | if (retval) |
1319 | return retval; | 1363 | return retval; |
@@ -1379,10 +1423,10 @@ EXPORT_SYMBOL(search_binary_handler); | |||
1379 | /* | 1423 | /* |
1380 | * sys_execve() executes a new program. | 1424 | * sys_execve() executes a new program. |
1381 | */ | 1425 | */ |
1382 | int do_execve(const char * filename, | 1426 | static int do_execve_common(const char *filename, |
1383 | const char __user *const __user *argv, | 1427 | struct user_arg_ptr argv, |
1384 | const char __user *const __user *envp, | 1428 | struct user_arg_ptr envp, |
1385 | struct pt_regs * regs) | 1429 | struct pt_regs *regs) |
1386 | { | 1430 | { |
1387 | struct linux_binprm *bprm; | 1431 | struct linux_binprm *bprm; |
1388 | struct file *file; | 1432 | struct file *file; |
@@ -1489,6 +1533,34 @@ out_ret: | |||
1489 | return retval; | 1533 | return retval; |
1490 | } | 1534 | } |
1491 | 1535 | ||
1536 | int do_execve(const char *filename, | ||
1537 | const char __user *const __user *__argv, | ||
1538 | const char __user *const __user *__envp, | ||
1539 | struct pt_regs *regs) | ||
1540 | { | ||
1541 | struct user_arg_ptr argv = { .ptr.native = __argv }; | ||
1542 | struct user_arg_ptr envp = { .ptr.native = __envp }; | ||
1543 | return do_execve_common(filename, argv, envp, regs); | ||
1544 | } | ||
1545 | |||
1546 | #ifdef CONFIG_COMPAT | ||
1547 | int compat_do_execve(char *filename, | ||
1548 | compat_uptr_t __user *__argv, | ||
1549 | compat_uptr_t __user *__envp, | ||
1550 | struct pt_regs *regs) | ||
1551 | { | ||
1552 | struct user_arg_ptr argv = { | ||
1553 | .is_compat = true, | ||
1554 | .ptr.compat = __argv, | ||
1555 | }; | ||
1556 | struct user_arg_ptr envp = { | ||
1557 | .is_compat = true, | ||
1558 | .ptr.compat = __envp, | ||
1559 | }; | ||
1560 | return do_execve_common(filename, argv, envp, regs); | ||
1561 | } | ||
1562 | #endif | ||
1563 | |||
1492 | void set_binfmt(struct linux_binfmt *new) | 1564 | void set_binfmt(struct linux_binfmt *new) |
1493 | { | 1565 | { |
1494 | struct mm_struct *mm = current->mm; | 1566 | struct mm_struct *mm = current->mm; |
@@ -1548,6 +1620,41 @@ expand_fail: | |||
1548 | return ret; | 1620 | return ret; |
1549 | } | 1621 | } |
1550 | 1622 | ||
1623 | static int cn_print_exe_file(struct core_name *cn) | ||
1624 | { | ||
1625 | struct file *exe_file; | ||
1626 | char *pathbuf, *path, *p; | ||
1627 | int ret; | ||
1628 | |||
1629 | exe_file = get_mm_exe_file(current->mm); | ||
1630 | if (!exe_file) | ||
1631 | return cn_printf(cn, "(unknown)"); | ||
1632 | |||
1633 | pathbuf = kmalloc(PATH_MAX, GFP_TEMPORARY); | ||
1634 | if (!pathbuf) { | ||
1635 | ret = -ENOMEM; | ||
1636 | goto put_exe_file; | ||
1637 | } | ||
1638 | |||
1639 | path = d_path(&exe_file->f_path, pathbuf, PATH_MAX); | ||
1640 | if (IS_ERR(path)) { | ||
1641 | ret = PTR_ERR(path); | ||
1642 | goto free_buf; | ||
1643 | } | ||
1644 | |||
1645 | for (p = path; *p; p++) | ||
1646 | if (*p == '/') | ||
1647 | *p = '!'; | ||
1648 | |||
1649 | ret = cn_printf(cn, "%s", path); | ||
1650 | |||
1651 | free_buf: | ||
1652 | kfree(pathbuf); | ||
1653 | put_exe_file: | ||
1654 | fput(exe_file); | ||
1655 | return ret; | ||
1656 | } | ||
1657 | |||
1551 | /* format_corename will inspect the pattern parameter, and output a | 1658 | /* format_corename will inspect the pattern parameter, and output a |
1552 | * name into corename, which must have space for at least | 1659 | * name into corename, which must have space for at least |
1553 | * CORENAME_MAX_SIZE bytes plus one byte for the zero terminator. | 1660 | * CORENAME_MAX_SIZE bytes plus one byte for the zero terminator. |
@@ -1619,6 +1726,9 @@ static int format_corename(struct core_name *cn, long signr) | |||
1619 | case 'e': | 1726 | case 'e': |
1620 | err = cn_printf(cn, "%s", current->comm); | 1727 | err = cn_printf(cn, "%s", current->comm); |
1621 | break; | 1728 | break; |
1729 | case 'E': | ||
1730 | err = cn_print_exe_file(cn); | ||
1731 | break; | ||
1622 | /* core limit size */ | 1732 | /* core limit size */ |
1623 | case 'c': | 1733 | case 'c': |
1624 | err = cn_printf(cn, "%lu", | 1734 | err = cn_printf(cn, "%lu", |
@@ -1659,6 +1769,7 @@ static int zap_process(struct task_struct *start, int exit_code) | |||
1659 | 1769 | ||
1660 | t = start; | 1770 | t = start; |
1661 | do { | 1771 | do { |
1772 | task_clear_group_stop_pending(t); | ||
1662 | if (t != current && t->mm) { | 1773 | if (t != current && t->mm) { |
1663 | sigaddset(&t->pending.signal, SIGKILL); | 1774 | sigaddset(&t->pending.signal, SIGKILL); |
1664 | signal_wake_up(t, 1); | 1775 | signal_wake_up(t, 1); |
@@ -1885,7 +1996,7 @@ static void wait_for_dump_helpers(struct file *file) | |||
1885 | * is a special value that we use to trap recursive | 1996 | * is a special value that we use to trap recursive |
1886 | * core dumps | 1997 | * core dumps |
1887 | */ | 1998 | */ |
1888 | static int umh_pipe_setup(struct subprocess_info *info) | 1999 | static int umh_pipe_setup(struct subprocess_info *info, struct cred *new) |
1889 | { | 2000 | { |
1890 | struct file *rp, *wp; | 2001 | struct file *rp, *wp; |
1891 | struct fdtable *fdt; | 2002 | struct fdtable *fdt; |