exec.c (ea77f7a2e8561012cf100c530170f12351c3b53e) exec.c (3864601387cf4196371e3c1897fdffa5228296f9)
1/*
2 * linux/fs/exec.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */
6
7/*
8 * #!-checking implemented by tytso.

--- 28 unchanged lines hidden (view full) ---

37#include <linux/spinlock.h>
38#include <linux/key.h>
39#include <linux/personality.h>
40#include <linux/binfmts.h>
41#include <linux/utsname.h>
42#include <linux/pid_namespace.h>
43#include <linux/module.h>
44#include <linux/namei.h>
1/*
2 * linux/fs/exec.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */
6
7/*
8 * #!-checking implemented by tytso.

--- 28 unchanged lines hidden (view full) ---

37#include <linux/spinlock.h>
38#include <linux/key.h>
39#include <linux/personality.h>
40#include <linux/binfmts.h>
41#include <linux/utsname.h>
42#include <linux/pid_namespace.h>
43#include <linux/module.h>
44#include <linux/namei.h>
45#include <linux/proc_fs.h>
46#include <linux/mount.h>
47#include <linux/security.h>
48#include <linux/syscalls.h>
49#include <linux/tsacct_kern.h>
50#include <linux/cn_proc.h>
51#include <linux/audit.h>
52#include <linux/tracehook.h>
53#include <linux/kmod.h>
54#include <linux/fsnotify.h>
55#include <linux/fs_struct.h>
56#include <linux/pipe_fs_i.h>
57#include <linux/oom.h>
45#include <linux/mount.h>
46#include <linux/security.h>
47#include <linux/syscalls.h>
48#include <linux/tsacct_kern.h>
49#include <linux/cn_proc.h>
50#include <linux/audit.h>
51#include <linux/tracehook.h>
52#include <linux/kmod.h>
53#include <linux/fsnotify.h>
54#include <linux/fs_struct.h>
55#include <linux/pipe_fs_i.h>
56#include <linux/oom.h>
57#include <linux/compat.h>
58
59#include <asm/uaccess.h>
60#include <asm/mmu_context.h>
61#include <asm/tlb.h>
62#include "internal.h"
63
64int core_uses_pid;
65char core_pattern[CORENAME_MAX_SIZE] = "core";

--- 95 unchanged lines hidden (view full) ---

161 }
162exit:
163 fput(file);
164out:
165 return error;
166}
167
168#ifdef CONFIG_MMU
58
59#include <asm/uaccess.h>
60#include <asm/mmu_context.h>
61#include <asm/tlb.h>
62#include "internal.h"
63
64int core_uses_pid;
65char core_pattern[CORENAME_MAX_SIZE] = "core";

--- 95 unchanged lines hidden (view full) ---

161 }
162exit:
163 fput(file);
164out:
165 return error;
166}
167
168#ifdef CONFIG_MMU
169
170void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
169/*
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 */
175static void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
171{
172 struct mm_struct *mm = current->mm;
173 long diff = (long)(pages - bprm->vma_pages);
174
175 if (!mm || !diff)
176 return;
177
178 bprm->vma_pages = pages;
179
180#ifdef SPLIT_RSS_COUNTING
181 add_mm_counter(mm, MM_ANONPAGES, diff);
182#else
183 spin_lock(&mm->page_table_lock);
184 add_mm_counter(mm, MM_ANONPAGES, diff);
185 spin_unlock(&mm->page_table_lock);
186#endif
187}
188
176{
177 struct mm_struct *mm = current->mm;
178 long diff = (long)(pages - bprm->vma_pages);
179
180 if (!mm || !diff)
181 return;
182
183 bprm->vma_pages = pages;
184
185#ifdef SPLIT_RSS_COUNTING
186 add_mm_counter(mm, MM_ANONPAGES, diff);
187#else
188 spin_lock(&mm->page_table_lock);
189 add_mm_counter(mm, MM_ANONPAGES, diff);
190 spin_unlock(&mm->page_table_lock);
191#endif
192}
193
189struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
194static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
190 int write)
191{
192 struct page *page;
193 int ret;
194
195#ifdef CONFIG_STACK_GROWSUP
196 if (write) {
195 int write)
196{
197 struct page *page;
198 int ret;
199
200#ifdef CONFIG_STACK_GROWSUP
201 if (write) {
197 ret = expand_stack_downwards(bprm->vma, pos);
202 ret = expand_downwards(bprm->vma, pos);
198 if (ret < 0)
199 return NULL;
200 }
201#endif
202 ret = get_user_pages(current, bprm->mm, pos,
203 1, write, 1, &page, NULL);
204 if (ret <= 0)
205 return NULL;

--- 94 unchanged lines hidden (view full) ---

300
301static bool valid_arg_len(struct linux_binprm *bprm, long len)
302{
303 return len <= MAX_ARG_STRLEN;
304}
305
306#else
307
203 if (ret < 0)
204 return NULL;
205 }
206#endif
207 ret = get_user_pages(current, bprm->mm, pos,
208 1, write, 1, &page, NULL);
209 if (ret <= 0)
210 return NULL;

--- 94 unchanged lines hidden (view full) ---

305
306static bool valid_arg_len(struct linux_binprm *bprm, long len)
307{
308 return len <= MAX_ARG_STRLEN;
309}
310
311#else
312
308void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
313static inline void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
309{
310}
311
314{
315}
316
312struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
317static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
313 int write)
314{
315 struct page *page;
316
317 page = bprm->page[pos / PAGE_SIZE];
318 if (!page && write) {
319 page = alloc_page(GFP_HIGHUSER|__GFP_ZERO);
320 if (!page)

--- 72 unchanged lines hidden (view full) ---

393 if (mm) {
394 bprm->mm = NULL;
395 mmdrop(mm);
396 }
397
398 return err;
399}
400
318 int write)
319{
320 struct page *page;
321
322 page = bprm->page[pos / PAGE_SIZE];
323 if (!page && write) {
324 page = alloc_page(GFP_HIGHUSER|__GFP_ZERO);
325 if (!page)

--- 72 unchanged lines hidden (view full) ---

398 if (mm) {
399 bprm->mm = NULL;
400 mmdrop(mm);
401 }
402
403 return err;
404}
405
406struct 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
418static 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/*
402 * count() counts the number of strings in array ARGV.
403 */
439/*
440 * count() counts the number of strings in array ARGV.
441 */
404static int count(const char __user * const __user * argv, int max)
442static int count(struct user_arg_ptr argv, int max)
405{
406 int i = 0;
407
443{
444 int i = 0;
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)
415 break;
450 if (!p)
451 break;
416 argv++;
452
453 if (IS_ERR(p))
454 return -EFAULT;
455
417 if (i++ >= max)
418 return -E2BIG;
419
420 if (fatal_signal_pending(current))
421 return -ERESTARTNOHAND;
422 cond_resched();
423 }
424 }
425 return i;
426}
427
428/*
429 * 'copy_strings()' copies argument/environment strings from the old
430 * 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.
432 */
456 if (i++ >= max)
457 return -E2BIG;
458
459 if (fatal_signal_pending(current))
460 return -ERESTARTNOHAND;
461 cond_resched();
462 }
463 }
464 return i;
465}
466
467/*
468 * 'copy_strings()' copies argument/environment strings from the old
469 * processes's memory to the new process's stack. The call to get_user_pages()
470 * ensures the destination page is created and not swapped out.
471 */
433static int copy_strings(int argc, const char __user *const __user *argv,
472static int copy_strings(int argc, struct user_arg_ptr argv,
434 struct linux_binprm *bprm)
435{
436 struct page *kmapped_page = NULL;
437 char *kaddr = NULL;
438 unsigned long kpos = 0;
439 int ret;
440
441 while (argc-- > 0) {
442 const char __user *str;
443 int len;
444 unsigned long pos;
445
473 struct linux_binprm *bprm)
474{
475 struct page *kmapped_page = NULL;
476 char *kaddr = NULL;
477 unsigned long kpos = 0;
478 int ret;
479
480 while (argc-- > 0) {
481 const char __user *str;
482 int len;
483 unsigned long pos;
484
446 if (get_user(str, argv+argc) ||
447 !(len = strnlen_user(str, MAX_ARG_STRLEN))) {
448 ret = -EFAULT;
485 ret = -EFAULT;
486 str = get_user_arg_ptr(argv, argc);
487 if (IS_ERR(str))
449 goto out;
488 goto out;
450 }
451
489
452 if (!valid_arg_len(bprm, len)) {
453 ret = -E2BIG;
490 len = strnlen_user(str, MAX_ARG_STRLEN);
491 if (!len)
454 goto out;
492 goto out;
455 }
456
493
494 ret = -E2BIG;
495 if (!valid_arg_len(bprm, len))
496 goto out;
497
457 /* We're going to work our way backwords. */
458 pos = bprm->p;
459 str += len;
460 bprm->p -= len;
461
462 while (len > 0) {
463 int offset, bytes_to_copy;
464

--- 49 unchanged lines hidden (view full) ---

514 put_arg_page(kmapped_page);
515 }
516 return ret;
517}
518
519/*
520 * Like copy_strings, but get argv and its values from kernel memory.
521 */
498 /* We're going to work our way backwords. */
499 pos = bprm->p;
500 str += len;
501 bprm->p -= len;
502
503 while (len > 0) {
504 int offset, bytes_to_copy;
505

--- 49 unchanged lines hidden (view full) ---

555 put_arg_page(kmapped_page);
556 }
557 return ret;
558}
559
560/*
561 * Like copy_strings, but get argv and its values from kernel memory.
562 */
522int copy_strings_kernel(int argc, const char *const *argv,
563int copy_strings_kernel(int argc, const char *const *__argv,
523 struct linux_binprm *bprm)
524{
525 int r;
526 mm_segment_t oldfs = get_fs();
564 struct linux_binprm *bprm)
565{
566 int r;
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;
531}
532EXPORT_SYMBOL(copy_strings_kernel);
533
534#ifdef CONFIG_MMU
535
536/*
537 * During bprm_mm_init(), we create a temporary stack at STACK_TOP_MAX. Once

--- 10 unchanged lines hidden (view full) ---

548static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
549{
550 struct mm_struct *mm = vma->vm_mm;
551 unsigned long old_start = vma->vm_start;
552 unsigned long old_end = vma->vm_end;
553 unsigned long length = old_end - old_start;
554 unsigned long new_start = old_start - shift;
555 unsigned long new_end = old_end - shift;
576 return r;
577}
578EXPORT_SYMBOL(copy_strings_kernel);
579
580#ifdef CONFIG_MMU
581
582/*
583 * During bprm_mm_init(), we create a temporary stack at STACK_TOP_MAX. Once

--- 10 unchanged lines hidden (view full) ---

594static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
595{
596 struct mm_struct *mm = vma->vm_mm;
597 unsigned long old_start = vma->vm_start;
598 unsigned long old_end = vma->vm_end;
599 unsigned long length = old_end - old_start;
600 unsigned long new_start = old_start - shift;
601 unsigned long new_end = old_end - shift;
556 struct mmu_gather *tlb;
602 struct mmu_gather tlb;
557
558 BUG_ON(new_start > new_end);
559
560 /*
561 * ensure there are no vmas between where we want to go
562 * and where we are
563 */
564 if (vma != find_vma(mm, new_start))

--- 9 unchanged lines hidden (view full) ---

574 * move the page tables downwards, on failure we rely on
575 * process cleanup to remove whatever mess we made.
576 */
577 if (length != move_page_tables(vma, old_start,
578 vma, new_start, length))
579 return -ENOMEM;
580
581 lru_add_drain();
603
604 BUG_ON(new_start > new_end);
605
606 /*
607 * ensure there are no vmas between where we want to go
608 * and where we are
609 */
610 if (vma != find_vma(mm, new_start))

--- 9 unchanged lines hidden (view full) ---

620 * move the page tables downwards, on failure we rely on
621 * process cleanup to remove whatever mess we made.
622 */
623 if (length != move_page_tables(vma, old_start,
624 vma, new_start, length))
625 return -ENOMEM;
626
627 lru_add_drain();
582 tlb = tlb_gather_mmu(mm, 0);
628 tlb_gather_mmu(&tlb, mm, 0);
583 if (new_end > old_start) {
584 /*
585 * when the old and new regions overlap clear from new_end.
586 */
629 if (new_end > old_start) {
630 /*
631 * when the old and new regions overlap clear from new_end.
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);
589 } else {
590 /*
591 * otherwise, clean from old_start; this is done to not touch
592 * the address space in [new_end, old_start) some architectures
593 * have constraints on va-space that make this illegal (IA64) -
594 * for the others its just a little faster.
595 */
634 vma->vm_next ? vma->vm_next->vm_start : 0);
635 } else {
636 /*
637 * otherwise, clean from old_start; this is done to not touch
638 * the address space in [new_end, old_start) some architectures
639 * have constraints on va-space that make this illegal (IA64) -
640 * for the others its just a little faster.
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);
598 }
643 vma->vm_next ? vma->vm_next->vm_start : 0);
644 }
599 tlb_finish_mmu(tlb, new_end, old_end);
645 tlb_finish_mmu(&tlb, new_end, old_end);
600
601 /*
602 * Shrink the vma to just the new range. Always succeeds.
603 */
604 vma_adjust(vma, new_start, new_end, vma->vm_pgoff, NULL);
605
606 return 0;
607}

--- 391 unchanged lines hidden (view full) ---

999char *get_task_comm(char *buf, struct task_struct *tsk)
1000{
1001 /* buf must be at least sizeof(tsk->comm) in size */
1002 task_lock(tsk);
1003 strncpy(buf, tsk->comm, sizeof(tsk->comm));
1004 task_unlock(tsk);
1005 return buf;
1006}
646
647 /*
648 * Shrink the vma to just the new range. Always succeeds.
649 */
650 vma_adjust(vma, new_start, new_end, vma->vm_pgoff, NULL);
651
652 return 0;
653}

--- 391 unchanged lines hidden (view full) ---

1045char *get_task_comm(char *buf, struct task_struct *tsk)
1046{
1047 /* buf must be at least sizeof(tsk->comm) in size */
1048 task_lock(tsk);
1049 strncpy(buf, tsk->comm, sizeof(tsk->comm));
1050 task_unlock(tsk);
1051 return buf;
1052}
1053EXPORT_SYMBOL_GPL(get_task_comm);
1007
1008void set_task_comm(struct task_struct *tsk, char *buf)
1009{
1010 task_lock(tsk);
1011
1012 /*
1013 * Threads may access current->comm without holding
1014 * the task lock, so write the string carefully.

--- 359 unchanged lines hidden (view full) ---

1374 return retval;
1375}
1376
1377EXPORT_SYMBOL(search_binary_handler);
1378
1379/*
1380 * sys_execve() executes a new program.
1381 */
1054
1055void set_task_comm(struct task_struct *tsk, char *buf)
1056{
1057 task_lock(tsk);
1058
1059 /*
1060 * Threads may access current->comm without holding
1061 * the task lock, so write the string carefully.

--- 359 unchanged lines hidden (view full) ---

1421 return retval;
1422}
1423
1424EXPORT_SYMBOL(search_binary_handler);
1425
1426/*
1427 * sys_execve() executes a new program.
1428 */
1382int do_execve(const char * filename,
1383 const char __user *const __user *argv,
1384 const char __user *const __user *envp,
1385 struct pt_regs * regs)
1429static int do_execve_common(const char *filename,
1430 struct user_arg_ptr argv,
1431 struct user_arg_ptr envp,
1432 struct pt_regs *regs)
1386{
1387 struct linux_binprm *bprm;
1388 struct file *file;
1389 struct files_struct *displaced;
1390 bool clear_in_exec;
1391 int retval;
1392
1393 retval = unshare_files(&displaced);

--- 90 unchanged lines hidden (view full) ---

1484
1485out_files:
1486 if (displaced)
1487 reset_files_struct(displaced);
1488out_ret:
1489 return retval;
1490}
1491
1433{
1434 struct linux_binprm *bprm;
1435 struct file *file;
1436 struct files_struct *displaced;
1437 bool clear_in_exec;
1438 int retval;
1439
1440 retval = unshare_files(&displaced);

--- 90 unchanged lines hidden (view full) ---

1531
1532out_files:
1533 if (displaced)
1534 reset_files_struct(displaced);
1535out_ret:
1536 return retval;
1537}
1538
1539int do_execve(const char *filename,
1540 const char __user *const __user *__argv,
1541 const char __user *const __user *__envp,
1542 struct pt_regs *regs)
1543{
1544 struct user_arg_ptr argv = { .ptr.native = __argv };
1545 struct user_arg_ptr envp = { .ptr.native = __envp };
1546 return do_execve_common(filename, argv, envp, regs);
1547}
1548
1549#ifdef CONFIG_COMPAT
1550int compat_do_execve(char *filename,
1551 compat_uptr_t __user *__argv,
1552 compat_uptr_t __user *__envp,
1553 struct pt_regs *regs)
1554{
1555 struct user_arg_ptr argv = {
1556 .is_compat = true,
1557 .ptr.compat = __argv,
1558 };
1559 struct user_arg_ptr envp = {
1560 .is_compat = true,
1561 .ptr.compat = __envp,
1562 };
1563 return do_execve_common(filename, argv, envp, regs);
1564}
1565#endif
1566
1492void set_binfmt(struct linux_binfmt *new)
1493{
1494 struct mm_struct *mm = current->mm;
1495
1496 if (mm->binfmt)
1497 module_put(mm->binfmt->module);
1498
1499 mm->binfmt = new;

--- 154 unchanged lines hidden (view full) ---

1654 int nr = 0;
1655
1656 start->signal->flags = SIGNAL_GROUP_EXIT;
1657 start->signal->group_exit_code = exit_code;
1658 start->signal->group_stop_count = 0;
1659
1660 t = start;
1661 do {
1567void set_binfmt(struct linux_binfmt *new)
1568{
1569 struct mm_struct *mm = current->mm;
1570
1571 if (mm->binfmt)
1572 module_put(mm->binfmt->module);
1573
1574 mm->binfmt = new;

--- 154 unchanged lines hidden (view full) ---

1729 int nr = 0;
1730
1731 start->signal->flags = SIGNAL_GROUP_EXIT;
1732 start->signal->group_exit_code = exit_code;
1733 start->signal->group_stop_count = 0;
1734
1735 t = start;
1736 do {
1737 task_clear_group_stop_pending(t);
1662 if (t != current && t->mm) {
1663 sigaddset(&t->pending.signal, SIGKILL);
1664 signal_wake_up(t, 1);
1665 nr++;
1666 }
1667 } while_each_thread(start, t);
1668
1669 return nr;

--- 465 unchanged lines hidden ---
1738 if (t != current && t->mm) {
1739 sigaddset(&t->pending.signal, SIGKILL);
1740 signal_wake_up(t, 1);
1741 nr++;
1742 }
1743 } while_each_thread(start, t);
1744
1745 return nr;

--- 465 unchanged lines hidden ---