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; |
