diff options
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 39 |
1 files changed, 27 insertions, 12 deletions
@@ -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 | */ |
364 | static int count(char __user * __user * argv, int max) | 364 | static 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 | */ |
390 | static int copy_strings(int argc, char __user * __user * argv, | 393 | static 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 | */ |
473 | int copy_strings_kernel(int argc,char ** argv, struct linux_binprm *bprm) | 482 | int 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); | |||
997 | void setup_new_exec(struct linux_binprm * bprm) | 1012 | void 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 | */ |
1319 | int do_execve(char * filename, | 1334 | int 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; |