aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c59
1 files changed, 27 insertions, 32 deletions
diff --git a/fs/exec.c b/fs/exec.c
index d8e1191cb112..a96a4885bbbf 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -123,7 +123,7 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
123 goto out; 123 goto out;
124 124
125 error = -EINVAL; 125 error = -EINVAL;
126 if (!S_ISREG(file->f_path.dentry->d_inode->i_mode)) 126 if (!S_ISREG(file_inode(file)->i_mode))
127 goto exit; 127 goto exit;
128 128
129 error = -EACCES; 129 error = -EACCES;
@@ -355,7 +355,7 @@ static bool valid_arg_len(struct linux_binprm *bprm, long len)
355 * flags, permissions, and offset, so we use temporary values. We'll update 355 * flags, permissions, and offset, so we use temporary values. We'll update
356 * them later in setup_arg_pages(). 356 * them later in setup_arg_pages().
357 */ 357 */
358int bprm_mm_init(struct linux_binprm *bprm) 358static int bprm_mm_init(struct linux_binprm *bprm)
359{ 359{
360 int err; 360 int err;
361 struct mm_struct *mm = NULL; 361 struct mm_struct *mm = NULL;
@@ -434,8 +434,9 @@ static int count(struct user_arg_ptr argv, int max)
434 if (IS_ERR(p)) 434 if (IS_ERR(p))
435 return -EFAULT; 435 return -EFAULT;
436 436
437 if (i++ >= max) 437 if (i >= max)
438 return -E2BIG; 438 return -E2BIG;
439 ++i;
439 440
440 if (fatal_signal_pending(current)) 441 if (fatal_signal_pending(current))
441 return -ERESTARTNOHAND; 442 return -ERESTARTNOHAND;
@@ -763,7 +764,7 @@ struct file *open_exec(const char *name)
763 goto out; 764 goto out;
764 765
765 err = -EACCES; 766 err = -EACCES;
766 if (!S_ISREG(file->f_path.dentry->d_inode->i_mode)) 767 if (!S_ISREG(file_inode(file)->i_mode))
767 goto exit; 768 goto exit;
768 769
769 if (file->f_path.mnt->mnt_flags & MNT_NOEXEC) 770 if (file->f_path.mnt->mnt_flags & MNT_NOEXEC)
@@ -1097,7 +1098,7 @@ EXPORT_SYMBOL(flush_old_exec);
1097 1098
1098void would_dump(struct linux_binprm *bprm, struct file *file) 1099void would_dump(struct linux_binprm *bprm, struct file *file)
1099{ 1100{
1100 if (inode_permission(file->f_path.dentry->d_inode, MAY_READ) < 0) 1101 if (inode_permission(file_inode(file), MAY_READ) < 0)
1101 bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP; 1102 bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
1102} 1103}
1103EXPORT_SYMBOL(would_dump); 1104EXPORT_SYMBOL(would_dump);
@@ -1110,7 +1111,7 @@ void setup_new_exec(struct linux_binprm * bprm)
1110 current->sas_ss_sp = current->sas_ss_size = 0; 1111 current->sas_ss_sp = current->sas_ss_size = 0;
1111 1112
1112 if (uid_eq(current_euid(), current_uid()) && gid_eq(current_egid(), current_gid())) 1113 if (uid_eq(current_euid(), current_uid()) && gid_eq(current_egid(), current_gid()))
1113 set_dumpable(current->mm, SUID_DUMPABLE_ENABLED); 1114 set_dumpable(current->mm, SUID_DUMP_USER);
1114 else 1115 else
1115 set_dumpable(current->mm, suid_dumpable); 1116 set_dumpable(current->mm, suid_dumpable);
1116 1117
@@ -1175,9 +1176,24 @@ void free_bprm(struct linux_binprm *bprm)
1175 mutex_unlock(&current->signal->cred_guard_mutex); 1176 mutex_unlock(&current->signal->cred_guard_mutex);
1176 abort_creds(bprm->cred); 1177 abort_creds(bprm->cred);
1177 } 1178 }
1179 /* If a binfmt changed the interp, free it. */
1180 if (bprm->interp != bprm->filename)
1181 kfree(bprm->interp);
1178 kfree(bprm); 1182 kfree(bprm);
1179} 1183}
1180 1184
1185int bprm_change_interp(char *interp, struct linux_binprm *bprm)
1186{
1187 /* If a binfmt changed the interp, free it first. */
1188 if (bprm->interp != bprm->filename)
1189 kfree(bprm->interp);
1190 bprm->interp = kstrdup(interp, GFP_KERNEL);
1191 if (!bprm->interp)
1192 return -ENOMEM;
1193 return 0;
1194}
1195EXPORT_SYMBOL(bprm_change_interp);
1196
1181/* 1197/*
1182 * install the new credentials for this executable 1198 * install the new credentials for this executable
1183 */ 1199 */
@@ -1254,7 +1270,7 @@ static int check_unsafe_exec(struct linux_binprm *bprm)
1254int prepare_binprm(struct linux_binprm *bprm) 1270int prepare_binprm(struct linux_binprm *bprm)
1255{ 1271{
1256 umode_t mode; 1272 umode_t mode;
1257 struct inode * inode = bprm->file->f_path.dentry->d_inode; 1273 struct inode * inode = file_inode(bprm->file);
1258 int retval; 1274 int retval;
1259 1275
1260 mode = inode->i_mode; 1276 mode = inode->i_mode;
@@ -1623,17 +1639,17 @@ EXPORT_SYMBOL(set_binfmt);
1623void set_dumpable(struct mm_struct *mm, int value) 1639void set_dumpable(struct mm_struct *mm, int value)
1624{ 1640{
1625 switch (value) { 1641 switch (value) {
1626 case SUID_DUMPABLE_DISABLED: 1642 case SUID_DUMP_DISABLE:
1627 clear_bit(MMF_DUMPABLE, &mm->flags); 1643 clear_bit(MMF_DUMPABLE, &mm->flags);
1628 smp_wmb(); 1644 smp_wmb();
1629 clear_bit(MMF_DUMP_SECURELY, &mm->flags); 1645 clear_bit(MMF_DUMP_SECURELY, &mm->flags);
1630 break; 1646 break;
1631 case SUID_DUMPABLE_ENABLED: 1647 case SUID_DUMP_USER:
1632 set_bit(MMF_DUMPABLE, &mm->flags); 1648 set_bit(MMF_DUMPABLE, &mm->flags);
1633 smp_wmb(); 1649 smp_wmb();
1634 clear_bit(MMF_DUMP_SECURELY, &mm->flags); 1650 clear_bit(MMF_DUMP_SECURELY, &mm->flags);
1635 break; 1651 break;
1636 case SUID_DUMPABLE_SAFE: 1652 case SUID_DUMP_ROOT:
1637 set_bit(MMF_DUMP_SECURELY, &mm->flags); 1653 set_bit(MMF_DUMP_SECURELY, &mm->flags);
1638 smp_wmb(); 1654 smp_wmb();
1639 set_bit(MMF_DUMPABLE, &mm->flags); 1655 set_bit(MMF_DUMPABLE, &mm->flags);
@@ -1646,7 +1662,7 @@ int __get_dumpable(unsigned long mm_flags)
1646 int ret; 1662 int ret;
1647 1663
1648 ret = mm_flags & MMF_DUMPABLE_MASK; 1664 ret = mm_flags & MMF_DUMPABLE_MASK;
1649 return (ret > SUID_DUMPABLE_ENABLED) ? SUID_DUMPABLE_SAFE : ret; 1665 return (ret > SUID_DUMP_USER) ? SUID_DUMP_ROOT : ret;
1650} 1666}
1651 1667
1652int get_dumpable(struct mm_struct *mm) 1668int get_dumpable(struct mm_struct *mm)
@@ -1654,7 +1670,6 @@ int get_dumpable(struct mm_struct *mm)
1654 return __get_dumpable(mm->flags); 1670 return __get_dumpable(mm->flags);
1655} 1671}
1656 1672
1657#ifdef __ARCH_WANT_SYS_EXECVE
1658SYSCALL_DEFINE3(execve, 1673SYSCALL_DEFINE3(execve,
1659 const char __user *, filename, 1674 const char __user *, filename,
1660 const char __user *const __user *, argv, 1675 const char __user *const __user *, argv,
@@ -1682,23 +1697,3 @@ asmlinkage long compat_sys_execve(const char __user * filename,
1682 return error; 1697 return error;
1683} 1698}
1684#endif 1699#endif
1685#endif
1686
1687#ifdef __ARCH_WANT_KERNEL_EXECVE
1688int kernel_execve(const char *filename,
1689 const char *const argv[],
1690 const char *const envp[])
1691{
1692 int ret = do_execve(filename,
1693 (const char __user *const __user *)argv,
1694 (const char __user *const __user *)envp);
1695 if (ret < 0)
1696 return ret;
1697
1698 /*
1699 * We were successful. We won't be returning to our caller, but
1700 * instead to user space by manipulating the kernel stack.
1701 */
1702 ret_from_kernel_execve(current_pt_regs());
1703}
1704#endif