aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c36
1 files changed, 25 insertions, 11 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 5e62d26a4fec..b12e24fe1c5e 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -398,6 +398,17 @@ err:
398 return err; 398 return err;
399} 399}
400 400
401static const char __user *
402get_user_arg_ptr(const char __user * const __user *argv, int nr)
403{
404 const char __user *ptr;
405
406 if (get_user(ptr, argv + nr))
407 return ERR_PTR(-EFAULT);
408
409 return ptr;
410}
411
401/* 412/*
402 * count() counts the number of strings in array ARGV. 413 * count() counts the number of strings in array ARGV.
403 */ 414 */
@@ -407,13 +418,14 @@ static int count(const char __user * const __user * argv, int max)
407 418
408 if (argv != NULL) { 419 if (argv != NULL) {
409 for (;;) { 420 for (;;) {
410 const char __user * p; 421 const char __user *p = get_user_arg_ptr(argv, i);
411 422
412 if (get_user(p, argv))
413 return -EFAULT;
414 if (!p) 423 if (!p)
415 break; 424 break;
416 argv++; 425
426 if (IS_ERR(p))
427 return -EFAULT;
428
417 if (i++ >= max) 429 if (i++ >= max)
418 return -E2BIG; 430 return -E2BIG;
419 431
@@ -443,16 +455,18 @@ static int copy_strings(int argc, const char __user *const __user *argv,
443 int len; 455 int len;
444 unsigned long pos; 456 unsigned long pos;
445 457
446 if (get_user(str, argv+argc) || 458 ret = -EFAULT;
447 !(len = strnlen_user(str, MAX_ARG_STRLEN))) { 459 str = get_user_arg_ptr(argv, argc);
448 ret = -EFAULT; 460 if (IS_ERR(str))
449 goto out; 461 goto out;
450 }
451 462
452 if (!valid_arg_len(bprm, len)) { 463 len = strnlen_user(str, MAX_ARG_STRLEN);
453 ret = -E2BIG; 464 if (!len)
465 goto out;
466
467 ret = -E2BIG;
468 if (!valid_arg_len(bprm, len))
454 goto out; 469 goto out;
455 }
456 470
457 /* We're going to work our way backwords. */ 471 /* We're going to work our way backwords. */
458 pos = bprm->p; 472 pos = bprm->p;