aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c201
1 files changed, 111 insertions, 90 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 929b58004b7e..172ceb6edde4 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -33,6 +33,7 @@
33#include <linux/string.h> 33#include <linux/string.h>
34#include <linux/init.h> 34#include <linux/init.h>
35#include <linux/pagemap.h> 35#include <linux/pagemap.h>
36#include <linux/perf_counter.h>
36#include <linux/highmem.h> 37#include <linux/highmem.h>
37#include <linux/spinlock.h> 38#include <linux/spinlock.h>
38#include <linux/key.h> 39#include <linux/key.h>
@@ -45,6 +46,7 @@
45#include <linux/proc_fs.h> 46#include <linux/proc_fs.h>
46#include <linux/mount.h> 47#include <linux/mount.h>
47#include <linux/security.h> 48#include <linux/security.h>
49#include <linux/ima.h>
48#include <linux/syscalls.h> 50#include <linux/syscalls.h>
49#include <linux/tsacct_kern.h> 51#include <linux/tsacct_kern.h>
50#include <linux/cn_proc.h> 52#include <linux/cn_proc.h>
@@ -52,6 +54,7 @@
52#include <linux/tracehook.h> 54#include <linux/tracehook.h>
53#include <linux/kmod.h> 55#include <linux/kmod.h>
54#include <linux/fsnotify.h> 56#include <linux/fsnotify.h>
57#include <linux/fs_struct.h>
55 58
56#include <asm/uaccess.h> 59#include <asm/uaccess.h>
57#include <asm/mmu_context.h> 60#include <asm/mmu_context.h>
@@ -67,17 +70,18 @@ int suid_dumpable = 0;
67static LIST_HEAD(formats); 70static LIST_HEAD(formats);
68static DEFINE_RWLOCK(binfmt_lock); 71static DEFINE_RWLOCK(binfmt_lock);
69 72
70int register_binfmt(struct linux_binfmt * fmt) 73int __register_binfmt(struct linux_binfmt * fmt, int insert)
71{ 74{
72 if (!fmt) 75 if (!fmt)
73 return -EINVAL; 76 return -EINVAL;
74 write_lock(&binfmt_lock); 77 write_lock(&binfmt_lock);
75 list_add(&fmt->lh, &formats); 78 insert ? list_add(&fmt->lh, &formats) :
79 list_add_tail(&fmt->lh, &formats);
76 write_unlock(&binfmt_lock); 80 write_unlock(&binfmt_lock);
77 return 0; 81 return 0;
78} 82}
79 83
80EXPORT_SYMBOL(register_binfmt); 84EXPORT_SYMBOL(__register_binfmt);
81 85
82void unregister_binfmt(struct linux_binfmt * fmt) 86void unregister_binfmt(struct linux_binfmt * fmt)
83{ 87{
@@ -102,37 +106,28 @@ static inline void put_binfmt(struct linux_binfmt * fmt)
102SYSCALL_DEFINE1(uselib, const char __user *, library) 106SYSCALL_DEFINE1(uselib, const char __user *, library)
103{ 107{
104 struct file *file; 108 struct file *file;
105 struct nameidata nd;
106 char *tmp = getname(library); 109 char *tmp = getname(library);
107 int error = PTR_ERR(tmp); 110 int error = PTR_ERR(tmp);
108 111
109 if (!IS_ERR(tmp)) { 112 if (IS_ERR(tmp))
110 error = path_lookup_open(AT_FDCWD, tmp, 113 goto out;
111 LOOKUP_FOLLOW, &nd, 114
112 FMODE_READ|FMODE_EXEC); 115 file = do_filp_open(AT_FDCWD, tmp,
113 putname(tmp); 116 O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
114 } 117 MAY_READ | MAY_EXEC | MAY_OPEN);
115 if (error) 118 putname(tmp);
119 error = PTR_ERR(file);
120 if (IS_ERR(file))
116 goto out; 121 goto out;
117 122
118 error = -EINVAL; 123 error = -EINVAL;
119 if (!S_ISREG(nd.path.dentry->d_inode->i_mode)) 124 if (!S_ISREG(file->f_path.dentry->d_inode->i_mode))
120 goto exit; 125 goto exit;
121 126
122 error = -EACCES; 127 error = -EACCES;
123 if (nd.path.mnt->mnt_flags & MNT_NOEXEC) 128 if (file->f_path.mnt->mnt_flags & MNT_NOEXEC)
124 goto exit; 129 goto exit;
125 130
126 error = inode_permission(nd.path.dentry->d_inode,
127 MAY_READ | MAY_EXEC | MAY_OPEN);
128 if (error)
129 goto exit;
130
131 file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
132 error = PTR_ERR(file);
133 if (IS_ERR(file))
134 goto out;
135
136 fsnotify_open(file->f_path.dentry); 131 fsnotify_open(file->f_path.dentry);
137 132
138 error = -ENOEXEC; 133 error = -ENOEXEC;
@@ -154,13 +149,10 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
154 } 149 }
155 read_unlock(&binfmt_lock); 150 read_unlock(&binfmt_lock);
156 } 151 }
152exit:
157 fput(file); 153 fput(file);
158out: 154out:
159 return error; 155 return error;
160exit:
161 release_open_intent(&nd);
162 path_put(&nd.path);
163 goto out;
164} 156}
165 157
166#ifdef CONFIG_MMU 158#ifdef CONFIG_MMU
@@ -655,50 +647,39 @@ EXPORT_SYMBOL(setup_arg_pages);
655 647
656struct file *open_exec(const char *name) 648struct file *open_exec(const char *name)
657{ 649{
658 struct nameidata nd;
659 struct file *file; 650 struct file *file;
660 int err; 651 int err;
661 652
662 err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd, 653 file = do_filp_open(AT_FDCWD, name,
663 FMODE_READ|FMODE_EXEC); 654 O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
664 if (err) 655 MAY_EXEC | MAY_OPEN);
656 if (IS_ERR(file))
665 goto out; 657 goto out;
666 658
667 err = -EACCES; 659 err = -EACCES;
668 if (!S_ISREG(nd.path.dentry->d_inode->i_mode)) 660 if (!S_ISREG(file->f_path.dentry->d_inode->i_mode))
669 goto out_path_put; 661 goto exit;
670
671 if (nd.path.mnt->mnt_flags & MNT_NOEXEC)
672 goto out_path_put;
673
674 err = inode_permission(nd.path.dentry->d_inode, MAY_EXEC | MAY_OPEN);
675 if (err)
676 goto out_path_put;
677 662
678 file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE); 663 if (file->f_path.mnt->mnt_flags & MNT_NOEXEC)
679 if (IS_ERR(file)) 664 goto exit;
680 return file;
681 665
682 fsnotify_open(file->f_path.dentry); 666 fsnotify_open(file->f_path.dentry);
683 667
684 err = deny_write_access(file); 668 err = deny_write_access(file);
685 if (err) { 669 if (err)
686 fput(file); 670 goto exit;
687 goto out;
688 }
689 671
672out:
690 return file; 673 return file;
691 674
692 out_path_put: 675exit:
693 release_open_intent(&nd); 676 fput(file);
694 path_put(&nd.path);
695 out:
696 return ERR_PTR(err); 677 return ERR_PTR(err);
697} 678}
698EXPORT_SYMBOL(open_exec); 679EXPORT_SYMBOL(open_exec);
699 680
700int kernel_read(struct file *file, unsigned long offset, 681int kernel_read(struct file *file, loff_t offset,
701 char *addr, unsigned long count) 682 char *addr, unsigned long count)
702{ 683{
703 mm_segment_t old_fs; 684 mm_segment_t old_fs;
704 loff_t pos = offset; 685 loff_t pos = offset;
@@ -942,6 +923,7 @@ void set_task_comm(struct task_struct *tsk, char *buf)
942 task_lock(tsk); 923 task_lock(tsk);
943 strlcpy(tsk->comm, buf, sizeof(tsk->comm)); 924 strlcpy(tsk->comm, buf, sizeof(tsk->comm));
944 task_unlock(tsk); 925 task_unlock(tsk);
926 perf_counter_comm(tsk);
945} 927}
946 928
947int flush_old_exec(struct linux_binprm * bprm) 929int flush_old_exec(struct linux_binprm * bprm)
@@ -1010,6 +992,13 @@ int flush_old_exec(struct linux_binprm * bprm)
1010 992
1011 current->personality &= ~bprm->per_clear; 993 current->personality &= ~bprm->per_clear;
1012 994
995 /*
996 * Flush performance counters when crossing a
997 * security domain:
998 */
999 if (!get_dumpable(current->mm))
1000 perf_counter_exit_task(current);
1001
1013 /* An exec changes our domain. We are no longer part of the thread 1002 /* An exec changes our domain. We are no longer part of the thread
1014 group */ 1003 group */
1015 1004
@@ -1027,6 +1016,35 @@ out:
1027EXPORT_SYMBOL(flush_old_exec); 1016EXPORT_SYMBOL(flush_old_exec);
1028 1017
1029/* 1018/*
1019 * Prepare credentials and lock ->cred_guard_mutex.
1020 * install_exec_creds() commits the new creds and drops the lock.
1021 * Or, if exec fails before, free_bprm() should release ->cred and
1022 * and unlock.
1023 */
1024int prepare_bprm_creds(struct linux_binprm *bprm)
1025{
1026 if (mutex_lock_interruptible(&current->cred_guard_mutex))
1027 return -ERESTARTNOINTR;
1028
1029 bprm->cred = prepare_exec_creds();
1030 if (likely(bprm->cred))
1031 return 0;
1032
1033 mutex_unlock(&current->cred_guard_mutex);
1034 return -ENOMEM;
1035}
1036
1037void free_bprm(struct linux_binprm *bprm)
1038{
1039 free_arg_pages(bprm);
1040 if (bprm->cred) {
1041 mutex_unlock(&current->cred_guard_mutex);
1042 abort_creds(bprm->cred);
1043 }
1044 kfree(bprm);
1045}
1046
1047/*
1030 * install the new credentials for this executable 1048 * install the new credentials for this executable
1031 */ 1049 */
1032void install_exec_creds(struct linux_binprm *bprm) 1050void install_exec_creds(struct linux_binprm *bprm)
@@ -1035,46 +1053,50 @@ void install_exec_creds(struct linux_binprm *bprm)
1035 1053
1036 commit_creds(bprm->cred); 1054 commit_creds(bprm->cred);
1037 bprm->cred = NULL; 1055 bprm->cred = NULL;
1038 1056 /*
1039 /* cred_exec_mutex must be held at least to this point to prevent 1057 * cred_guard_mutex must be held at least to this point to prevent
1040 * ptrace_attach() from altering our determination of the task's 1058 * ptrace_attach() from altering our determination of the task's
1041 * credentials; any time after this it may be unlocked */ 1059 * credentials; any time after this it may be unlocked.
1042 1060 */
1043 security_bprm_committed_creds(bprm); 1061 security_bprm_committed_creds(bprm);
1062 mutex_unlock(&current->cred_guard_mutex);
1044} 1063}
1045EXPORT_SYMBOL(install_exec_creds); 1064EXPORT_SYMBOL(install_exec_creds);
1046 1065
1047/* 1066/*
1048 * determine how safe it is to execute the proposed program 1067 * determine how safe it is to execute the proposed program
1049 * - the caller must hold current->cred_exec_mutex to protect against 1068 * - the caller must hold current->cred_guard_mutex to protect against
1050 * PTRACE_ATTACH 1069 * PTRACE_ATTACH
1051 */ 1070 */
1052void check_unsafe_exec(struct linux_binprm *bprm, struct files_struct *files) 1071int check_unsafe_exec(struct linux_binprm *bprm)
1053{ 1072{
1054 struct task_struct *p = current, *t; 1073 struct task_struct *p = current, *t;
1055 unsigned long flags; 1074 unsigned n_fs;
1056 unsigned n_fs, n_files, n_sighand; 1075 int res = 0;
1057 1076
1058 bprm->unsafe = tracehook_unsafe_exec(p); 1077 bprm->unsafe = tracehook_unsafe_exec(p);
1059 1078
1060 n_fs = 1; 1079 n_fs = 1;
1061 n_files = 1; 1080 write_lock(&p->fs->lock);
1062 n_sighand = 1; 1081 rcu_read_lock();
1063 lock_task_sighand(p, &flags);
1064 for (t = next_thread(p); t != p; t = next_thread(t)) { 1082 for (t = next_thread(p); t != p; t = next_thread(t)) {
1065 if (t->fs == p->fs) 1083 if (t->fs == p->fs)
1066 n_fs++; 1084 n_fs++;
1067 if (t->files == files)
1068 n_files++;
1069 n_sighand++;
1070 } 1085 }
1086 rcu_read_unlock();
1071 1087
1072 if (atomic_read(&p->fs->count) > n_fs || 1088 if (p->fs->users > n_fs) {
1073 atomic_read(&p->files->count) > n_files ||
1074 atomic_read(&p->sighand->count) > n_sighand)
1075 bprm->unsafe |= LSM_UNSAFE_SHARE; 1089 bprm->unsafe |= LSM_UNSAFE_SHARE;
1090 } else {
1091 res = -EAGAIN;
1092 if (!p->fs->in_exec) {
1093 p->fs->in_exec = 1;
1094 res = 1;
1095 }
1096 }
1097 write_unlock(&p->fs->lock);
1076 1098
1077 unlock_task_sighand(p, &flags); 1099 return res;
1078} 1100}
1079 1101
1080/* 1102/*
@@ -1184,6 +1206,9 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
1184 retval = security_bprm_check(bprm); 1206 retval = security_bprm_check(bprm);
1185 if (retval) 1207 if (retval)
1186 return retval; 1208 return retval;
1209 retval = ima_bprm_check(bprm);
1210 if (retval)
1211 return retval;
1187 1212
1188 /* kernel module loader fixup */ 1213 /* kernel module loader fixup */
1189 /* so we don't try to load run modprobe in kernel space. */ 1214 /* so we don't try to load run modprobe in kernel space. */
@@ -1251,14 +1276,6 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
1251 1276
1252EXPORT_SYMBOL(search_binary_handler); 1277EXPORT_SYMBOL(search_binary_handler);
1253 1278
1254void free_bprm(struct linux_binprm *bprm)
1255{
1256 free_arg_pages(bprm);
1257 if (bprm->cred)
1258 abort_creds(bprm->cred);
1259 kfree(bprm);
1260}
1261
1262/* 1279/*
1263 * sys_execve() executes a new program. 1280 * sys_execve() executes a new program.
1264 */ 1281 */
@@ -1270,6 +1287,7 @@ int do_execve(char * filename,
1270 struct linux_binprm *bprm; 1287 struct linux_binprm *bprm;
1271 struct file *file; 1288 struct file *file;
1272 struct files_struct *displaced; 1289 struct files_struct *displaced;
1290 bool clear_in_exec;
1273 int retval; 1291 int retval;
1274 1292
1275 retval = unshare_files(&displaced); 1293 retval = unshare_files(&displaced);
@@ -1281,20 +1299,20 @@ int do_execve(char * filename,
1281 if (!bprm) 1299 if (!bprm)
1282 goto out_files; 1300 goto out_files;
1283 1301
1284 retval = mutex_lock_interruptible(&current->cred_exec_mutex); 1302 retval = prepare_bprm_creds(bprm);
1285 if (retval < 0) 1303 if (retval)
1286 goto out_free; 1304 goto out_free;
1287 1305
1288 retval = -ENOMEM; 1306 retval = check_unsafe_exec(bprm);
1289 bprm->cred = prepare_exec_creds(); 1307 if (retval < 0)
1290 if (!bprm->cred) 1308 goto out_free;
1291 goto out_unlock; 1309 clear_in_exec = retval;
1292 check_unsafe_exec(bprm, displaced); 1310 current->in_execve = 1;
1293 1311
1294 file = open_exec(filename); 1312 file = open_exec(filename);
1295 retval = PTR_ERR(file); 1313 retval = PTR_ERR(file);
1296 if (IS_ERR(file)) 1314 if (IS_ERR(file))
1297 goto out_unlock; 1315 goto out_unmark;
1298 1316
1299 sched_exec(); 1317 sched_exec();
1300 1318
@@ -1337,7 +1355,8 @@ int do_execve(char * filename,
1337 goto out; 1355 goto out;
1338 1356
1339 /* execve succeeded */ 1357 /* execve succeeded */
1340 mutex_unlock(&current->cred_exec_mutex); 1358 current->fs->in_exec = 0;
1359 current->in_execve = 0;
1341 acct_update_integrals(current); 1360 acct_update_integrals(current);
1342 free_bprm(bprm); 1361 free_bprm(bprm);
1343 if (displaced) 1362 if (displaced)
@@ -1354,8 +1373,10 @@ out_file:
1354 fput(bprm->file); 1373 fput(bprm->file);
1355 } 1374 }
1356 1375
1357out_unlock: 1376out_unmark:
1358 mutex_unlock(&current->cred_exec_mutex); 1377 if (clear_in_exec)
1378 current->fs->in_exec = 0;
1379 current->in_execve = 0;
1359 1380
1360out_free: 1381out_free:
1361 free_bprm(bprm); 1382 free_bprm(bprm);