aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/exec.c45
-rw-r--r--fs/namei.c30
2 files changed, 51 insertions, 24 deletions
diff --git a/fs/exec.c b/fs/exec.c
index e1529b4c79b1..3d78fccdd723 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -748,11 +748,10 @@ EXPORT_SYMBOL(setup_arg_pages);
748 748
749#endif /* CONFIG_MMU */ 749#endif /* CONFIG_MMU */
750 750
751struct file *open_exec(const char *name) 751static 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
787struct file *open_exec(const char *name)
788{
789 struct filename tmp = { .name = name };
790 return do_open_exec(&tmp);
791}
787EXPORT_SYMBOL(open_exec); 792EXPORT_SYMBOL(open_exec);
788 793
789int kernel_read(struct file *file, loff_t offset, 794int 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
1165void free_bprm(struct linux_binprm *bprm) 1170static 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 */
1435static int do_execve_common(const char *filename, 1440static 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);
1546out_ret: 1554out_ret:
1555 putname(filename);
1547 return retval; 1556 return retval;
1548} 1557}
1549 1558
1550int do_execve(const char *filename, 1559int 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
1560static int compat_do_execve(const char *filename, 1569static 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
1619asmlinkage long compat_sys_execve(const char __user * filename, 1622asmlinkage 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
diff --git a/fs/namei.c b/fs/namei.c
index d580df2e6804..385f7817bfcc 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -196,6 +196,7 @@ recopy:
196 goto error; 196 goto error;
197 197
198 result->uptr = filename; 198 result->uptr = filename;
199 result->aname = NULL;
199 audit_getname(result); 200 audit_getname(result);
200 return result; 201 return result;
201 202
@@ -210,6 +211,35 @@ getname(const char __user * filename)
210 return getname_flags(filename, 0, NULL); 211 return getname_flags(filename, 0, NULL);
211} 212}
212 213
214/*
215 * The "getname_kernel()" interface doesn't do pathnames longer
216 * than EMBEDDED_NAME_MAX. Deal with it - you're a kernel user.
217 */
218struct filename *
219getname_kernel(const char * filename)
220{
221 struct filename *result;
222 char *kname;
223 int len;
224
225 len = strlen(filename);
226 if (len >= EMBEDDED_NAME_MAX)
227 return ERR_PTR(-ENAMETOOLONG);
228
229 result = __getname();
230 if (unlikely(!result))
231 return ERR_PTR(-ENOMEM);
232
233 kname = (char *)result + sizeof(*result);
234 result->name = kname;
235 result->uptr = NULL;
236 result->aname = NULL;
237 result->separate = false;
238
239 strlcpy(kname, filename, EMBEDDED_NAME_MAX);
240 return result;
241}
242
213#ifdef CONFIG_AUDITSYSCALL 243#ifdef CONFIG_AUDITSYSCALL
214void putname(struct filename *name) 244void putname(struct filename *name)
215{ 245{