aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c79
1 files changed, 67 insertions, 12 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 7761837e4500..6d2b6f936858 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -361,13 +361,13 @@ err:
361/* 361/*
362 * count() counts the number of strings in array ARGV. 362 * count() counts the number of strings in array ARGV.
363 */ 363 */
364static int count(char __user * __user * argv, int max) 364static int count(const char __user * const __user * argv, int max)
365{ 365{
366 int i = 0; 366 int i = 0;
367 367
368 if (argv != NULL) { 368 if (argv != NULL) {
369 for (;;) { 369 for (;;) {
370 char __user * p; 370 const char __user * p;
371 371
372 if (get_user(p, argv)) 372 if (get_user(p, argv))
373 return -EFAULT; 373 return -EFAULT;
@@ -376,6 +376,9 @@ static int count(char __user * __user * argv, int max)
376 argv++; 376 argv++;
377 if (i++ >= max) 377 if (i++ >= max)
378 return -E2BIG; 378 return -E2BIG;
379
380 if (fatal_signal_pending(current))
381 return -ERESTARTNOHAND;
379 cond_resched(); 382 cond_resched();
380 } 383 }
381 } 384 }
@@ -387,7 +390,7 @@ static int count(char __user * __user * argv, int max)
387 * processes's memory to the new process's stack. The call to get_user_pages() 390 * processes's memory to the new process's stack. The call to get_user_pages()
388 * ensures the destination page is created and not swapped out. 391 * ensures the destination page is created and not swapped out.
389 */ 392 */
390static int copy_strings(int argc, char __user * __user * argv, 393static int copy_strings(int argc, const char __user *const __user *argv,
391 struct linux_binprm *bprm) 394 struct linux_binprm *bprm)
392{ 395{
393 struct page *kmapped_page = NULL; 396 struct page *kmapped_page = NULL;
@@ -396,7 +399,7 @@ static int copy_strings(int argc, char __user * __user * argv,
396 int ret; 399 int ret;
397 400
398 while (argc-- > 0) { 401 while (argc-- > 0) {
399 char __user *str; 402 const char __user *str;
400 int len; 403 int len;
401 unsigned long pos; 404 unsigned long pos;
402 405
@@ -419,6 +422,12 @@ static int copy_strings(int argc, char __user * __user * argv,
419 while (len > 0) { 422 while (len > 0) {
420 int offset, bytes_to_copy; 423 int offset, bytes_to_copy;
421 424
425 if (fatal_signal_pending(current)) {
426 ret = -ERESTARTNOHAND;
427 goto out;
428 }
429 cond_resched();
430
422 offset = pos % PAGE_SIZE; 431 offset = pos % PAGE_SIZE;
423 if (offset == 0) 432 if (offset == 0)
424 offset = PAGE_SIZE; 433 offset = PAGE_SIZE;
@@ -470,12 +479,13 @@ out:
470/* 479/*
471 * Like copy_strings, but get argv and its values from kernel memory. 480 * Like copy_strings, but get argv and its values from kernel memory.
472 */ 481 */
473int copy_strings_kernel(int argc,char ** argv, struct linux_binprm *bprm) 482int copy_strings_kernel(int argc, const char *const *argv,
483 struct linux_binprm *bprm)
474{ 484{
475 int r; 485 int r;
476 mm_segment_t oldfs = get_fs(); 486 mm_segment_t oldfs = get_fs();
477 set_fs(KERNEL_DS); 487 set_fs(KERNEL_DS);
478 r = copy_strings(argc, (char __user * __user *)argv, bprm); 488 r = copy_strings(argc, (const char __user *const __user *)argv, bprm);
479 set_fs(oldfs); 489 set_fs(oldfs);
480 return r; 490 return r;
481} 491}
@@ -593,6 +603,11 @@ int setup_arg_pages(struct linux_binprm *bprm,
593#else 603#else
594 stack_top = arch_align_stack(stack_top); 604 stack_top = arch_align_stack(stack_top);
595 stack_top = PAGE_ALIGN(stack_top); 605 stack_top = PAGE_ALIGN(stack_top);
606
607 if (unlikely(stack_top < mmap_min_addr) ||
608 unlikely(vma->vm_end - vma->vm_start >= stack_top - mmap_min_addr))
609 return -ENOMEM;
610
596 stack_shift = vma->vm_end - stack_top; 611 stack_shift = vma->vm_end - stack_top;
597 612
598 bprm->p -= stack_shift; 613 bprm->p -= stack_shift;
@@ -997,7 +1012,7 @@ EXPORT_SYMBOL(flush_old_exec);
997void setup_new_exec(struct linux_binprm * bprm) 1012void setup_new_exec(struct linux_binprm * bprm)
998{ 1013{
999 int i, ch; 1014 int i, ch;
1000 char * name; 1015 const char *name;
1001 char tcomm[sizeof(current->comm)]; 1016 char tcomm[sizeof(current->comm)];
1002 1017
1003 arch_pick_mmap_layout(current->mm); 1018 arch_pick_mmap_layout(current->mm);
@@ -1117,7 +1132,7 @@ int check_unsafe_exec(struct linux_binprm *bprm)
1117 bprm->unsafe = tracehook_unsafe_exec(p); 1132 bprm->unsafe = tracehook_unsafe_exec(p);
1118 1133
1119 n_fs = 1; 1134 n_fs = 1;
1120 write_lock(&p->fs->lock); 1135 spin_lock(&p->fs->lock);
1121 rcu_read_lock(); 1136 rcu_read_lock();
1122 for (t = next_thread(p); t != p; t = next_thread(t)) { 1137 for (t = next_thread(p); t != p; t = next_thread(t)) {
1123 if (t->fs == p->fs) 1138 if (t->fs == p->fs)
@@ -1134,7 +1149,7 @@ int check_unsafe_exec(struct linux_binprm *bprm)
1134 res = 1; 1149 res = 1;
1135 } 1150 }
1136 } 1151 }
1137 write_unlock(&p->fs->lock); 1152 spin_unlock(&p->fs->lock);
1138 1153
1139 return res; 1154 return res;
1140} 1155}
@@ -1316,9 +1331,9 @@ EXPORT_SYMBOL(search_binary_handler);
1316/* 1331/*
1317 * sys_execve() executes a new program. 1332 * sys_execve() executes a new program.
1318 */ 1333 */
1319int do_execve(char * filename, 1334int do_execve(const char * filename,
1320 char __user *__user *argv, 1335 const char __user *const __user *argv,
1321 char __user *__user *envp, 1336 const char __user *const __user *envp,
1322 struct pt_regs * regs) 1337 struct pt_regs * regs)
1323{ 1338{
1324 struct linux_binprm *bprm; 1339 struct linux_binprm *bprm;
@@ -1999,3 +2014,43 @@ fail_creds:
1999fail: 2014fail:
2000 return; 2015 return;
2001} 2016}
2017
2018/*
2019 * Core dumping helper functions. These are the only things you should
2020 * do on a core-file: use only these functions to write out all the
2021 * necessary info.
2022 */
2023int dump_write(struct file *file, const void *addr, int nr)
2024{
2025 return access_ok(VERIFY_READ, addr, nr) && file->f_op->write(file, addr, nr, &file->f_pos) == nr;
2026}
2027EXPORT_SYMBOL(dump_write);
2028
2029int dump_seek(struct file *file, loff_t off)
2030{
2031 int ret = 1;
2032
2033 if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
2034 if (file->f_op->llseek(file, off, SEEK_CUR) < 0)
2035 return 0;
2036 } else {
2037 char *buf = (char *)get_zeroed_page(GFP_KERNEL);
2038
2039 if (!buf)
2040 return 0;
2041 while (off > 0) {
2042 unsigned long n = off;
2043
2044 if (n > PAGE_SIZE)
2045 n = PAGE_SIZE;
2046 if (!dump_write(file, buf, n)) {
2047 ret = 0;
2048 break;
2049 }
2050 off -= n;
2051 }
2052 free_page((unsigned long)buf);
2053 }
2054 return ret;
2055}
2056EXPORT_SYMBOL(dump_seek);