diff options
Diffstat (limited to 'fs/exec.c')
| -rw-r--r-- | fs/exec.c | 45 |
1 files changed, 21 insertions, 24 deletions
| @@ -748,11 +748,10 @@ EXPORT_SYMBOL(setup_arg_pages); | |||
| 748 | 748 | ||
| 749 | #endif /* CONFIG_MMU */ | 749 | #endif /* CONFIG_MMU */ |
| 750 | 750 | ||
| 751 | struct file *open_exec(const char *name) | 751 | static struct file *do_open_exec(struct filename *name) |
| 752 | { | 752 | { |
| 753 | struct file *file; | 753 | struct file *file; |
| 754 | int err; | 754 | int err; |
| 755 | struct filename tmp = { .name = name }; | ||
| 756 | static const struct open_flags open_exec_flags = { | 755 | static const struct open_flags open_exec_flags = { |
| 757 | .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC, | 756 | .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC, |
| 758 | .acc_mode = MAY_EXEC | MAY_OPEN, | 757 | .acc_mode = MAY_EXEC | MAY_OPEN, |
| @@ -760,7 +759,7 @@ struct file *open_exec(const char *name) | |||
| 760 | .lookup_flags = LOOKUP_FOLLOW, | 759 | .lookup_flags = LOOKUP_FOLLOW, |
| 761 | }; | 760 | }; |
| 762 | 761 | ||
| 763 | file = do_filp_open(AT_FDCWD, &tmp, &open_exec_flags); | 762 | file = do_filp_open(AT_FDCWD, name, &open_exec_flags); |
| 764 | if (IS_ERR(file)) | 763 | if (IS_ERR(file)) |
| 765 | goto out; | 764 | goto out; |
| 766 | 765 | ||
| @@ -784,6 +783,12 @@ exit: | |||
| 784 | fput(file); | 783 | fput(file); |
| 785 | return ERR_PTR(err); | 784 | return ERR_PTR(err); |
| 786 | } | 785 | } |
| 786 | |||
| 787 | struct file *open_exec(const char *name) | ||
| 788 | { | ||
| 789 | struct filename tmp = { .name = name }; | ||
| 790 | return do_open_exec(&tmp); | ||
| 791 | } | ||
| 787 | EXPORT_SYMBOL(open_exec); | 792 | EXPORT_SYMBOL(open_exec); |
| 788 | 793 | ||
| 789 | int kernel_read(struct file *file, loff_t offset, | 794 | int kernel_read(struct file *file, loff_t offset, |
| @@ -1162,7 +1167,7 @@ int prepare_bprm_creds(struct linux_binprm *bprm) | |||
| 1162 | return -ENOMEM; | 1167 | return -ENOMEM; |
| 1163 | } | 1168 | } |
| 1164 | 1169 | ||
| 1165 | void free_bprm(struct linux_binprm *bprm) | 1170 | static void free_bprm(struct linux_binprm *bprm) |
| 1166 | { | 1171 | { |
| 1167 | free_arg_pages(bprm); | 1172 | free_arg_pages(bprm); |
| 1168 | if (bprm->cred) { | 1173 | if (bprm->cred) { |
| @@ -1432,7 +1437,7 @@ static int exec_binprm(struct linux_binprm *bprm) | |||
| 1432 | /* | 1437 | /* |
| 1433 | * sys_execve() executes a new program. | 1438 | * sys_execve() executes a new program. |
| 1434 | */ | 1439 | */ |
| 1435 | static int do_execve_common(const char *filename, | 1440 | static int do_execve_common(struct filename *filename, |
| 1436 | struct user_arg_ptr argv, | 1441 | struct user_arg_ptr argv, |
| 1437 | struct user_arg_ptr envp) | 1442 | struct user_arg_ptr envp) |
| 1438 | { | 1443 | { |
| @@ -1441,6 +1446,9 @@ static int do_execve_common(const char *filename, | |||
| 1441 | struct files_struct *displaced; | 1446 | struct files_struct *displaced; |
| 1442 | int retval; | 1447 | int retval; |
| 1443 | 1448 | ||
| 1449 | if (IS_ERR(filename)) | ||
| 1450 | return PTR_ERR(filename); | ||
| 1451 | |||
| 1444 | /* | 1452 | /* |
| 1445 | * We move the actual failure in case of RLIMIT_NPROC excess from | 1453 | * We move the actual failure in case of RLIMIT_NPROC excess from |
| 1446 | * set*uid() to execve() because too many poorly written programs | 1454 | * set*uid() to execve() because too many poorly written programs |
| @@ -1473,7 +1481,7 @@ static int do_execve_common(const char *filename, | |||
| 1473 | check_unsafe_exec(bprm); | 1481 | check_unsafe_exec(bprm); |
| 1474 | current->in_execve = 1; | 1482 | current->in_execve = 1; |
| 1475 | 1483 | ||
| 1476 | file = open_exec(filename); | 1484 | file = do_open_exec(filename); |
| 1477 | retval = PTR_ERR(file); | 1485 | retval = PTR_ERR(file); |
| 1478 | if (IS_ERR(file)) | 1486 | if (IS_ERR(file)) |
| 1479 | goto out_unmark; | 1487 | goto out_unmark; |
| @@ -1481,8 +1489,7 @@ static int do_execve_common(const char *filename, | |||
| 1481 | sched_exec(); | 1489 | sched_exec(); |
| 1482 | 1490 | ||
| 1483 | bprm->file = file; | 1491 | bprm->file = file; |
| 1484 | bprm->filename = filename; | 1492 | bprm->filename = bprm->interp = filename->name; |
| 1485 | bprm->interp = filename; | ||
| 1486 | 1493 | ||
| 1487 | retval = bprm_mm_init(bprm); | 1494 | retval = bprm_mm_init(bprm); |
| 1488 | if (retval) | 1495 | if (retval) |
| @@ -1523,6 +1530,7 @@ static int do_execve_common(const char *filename, | |||
| 1523 | acct_update_integrals(current); | 1530 | acct_update_integrals(current); |
| 1524 | task_numa_free(current); | 1531 | task_numa_free(current); |
| 1525 | free_bprm(bprm); | 1532 | free_bprm(bprm); |
| 1533 | putname(filename); | ||
| 1526 | if (displaced) | 1534 | if (displaced) |
| 1527 | put_files_struct(displaced); | 1535 | put_files_struct(displaced); |
| 1528 | return retval; | 1536 | return retval; |
| @@ -1544,10 +1552,11 @@ out_files: | |||
| 1544 | if (displaced) | 1552 | if (displaced) |
| 1545 | reset_files_struct(displaced); | 1553 | reset_files_struct(displaced); |
| 1546 | out_ret: | 1554 | out_ret: |
| 1555 | putname(filename); | ||
| 1547 | return retval; | 1556 | return retval; |
| 1548 | } | 1557 | } |
| 1549 | 1558 | ||
| 1550 | int do_execve(const char *filename, | 1559 | int do_execve(struct filename *filename, |
| 1551 | const char __user *const __user *__argv, | 1560 | const char __user *const __user *__argv, |
| 1552 | const char __user *const __user *__envp) | 1561 | const char __user *const __user *__envp) |
| 1553 | { | 1562 | { |
| @@ -1557,7 +1566,7 @@ int do_execve(const char *filename, | |||
| 1557 | } | 1566 | } |
| 1558 | 1567 | ||
| 1559 | #ifdef CONFIG_COMPAT | 1568 | #ifdef CONFIG_COMPAT |
| 1560 | static int compat_do_execve(const char *filename, | 1569 | static int compat_do_execve(struct filename *filename, |
| 1561 | const compat_uptr_t __user *__argv, | 1570 | const compat_uptr_t __user *__argv, |
| 1562 | const compat_uptr_t __user *__envp) | 1571 | const compat_uptr_t __user *__envp) |
| 1563 | { | 1572 | { |
| @@ -1607,25 +1616,13 @@ SYSCALL_DEFINE3(execve, | |||
| 1607 | const char __user *const __user *, argv, | 1616 | const char __user *const __user *, argv, |
| 1608 | const char __user *const __user *, envp) | 1617 | const char __user *const __user *, envp) |
| 1609 | { | 1618 | { |
| 1610 | struct filename *path = getname(filename); | 1619 | return do_execve(getname(filename), argv, envp); |
| 1611 | int error = PTR_ERR(path); | ||
| 1612 | if (!IS_ERR(path)) { | ||
| 1613 | error = do_execve(path->name, argv, envp); | ||
| 1614 | putname(path); | ||
| 1615 | } | ||
| 1616 | return error; | ||
| 1617 | } | 1620 | } |
| 1618 | #ifdef CONFIG_COMPAT | 1621 | #ifdef CONFIG_COMPAT |
| 1619 | asmlinkage long compat_sys_execve(const char __user * filename, | 1622 | asmlinkage long compat_sys_execve(const char __user * filename, |
| 1620 | const compat_uptr_t __user * argv, | 1623 | const compat_uptr_t __user * argv, |
| 1621 | const compat_uptr_t __user * envp) | 1624 | const compat_uptr_t __user * envp) |
| 1622 | { | 1625 | { |
| 1623 | struct filename *path = getname(filename); | 1626 | return compat_do_execve(getname(filename), argv, envp); |
| 1624 | int error = PTR_ERR(path); | ||
| 1625 | if (!IS_ERR(path)) { | ||
| 1626 | error = compat_do_execve(path->name, argv, envp); | ||
| 1627 | putname(path); | ||
| 1628 | } | ||
| 1629 | return error; | ||
| 1630 | } | 1627 | } |
| 1631 | #endif | 1628 | #endif |
