aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c41
1 files changed, 35 insertions, 6 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 0dd60a01f1b4..b9f1c144b7a1 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -45,6 +45,7 @@
45#include <linux/proc_fs.h> 45#include <linux/proc_fs.h>
46#include <linux/mount.h> 46#include <linux/mount.h>
47#include <linux/security.h> 47#include <linux/security.h>
48#include <linux/ima.h>
48#include <linux/syscalls.h> 49#include <linux/syscalls.h>
49#include <linux/tsacct_kern.h> 50#include <linux/tsacct_kern.h>
50#include <linux/cn_proc.h> 51#include <linux/cn_proc.h>
@@ -127,6 +128,9 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
127 MAY_READ | MAY_EXEC | MAY_OPEN); 128 MAY_READ | MAY_EXEC | MAY_OPEN);
128 if (error) 129 if (error)
129 goto exit; 130 goto exit;
131 error = ima_path_check(&nd.path, MAY_READ | MAY_EXEC | MAY_OPEN);
132 if (error)
133 goto exit;
130 134
131 file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE); 135 file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
132 error = PTR_ERR(file); 136 error = PTR_ERR(file);
@@ -674,6 +678,9 @@ struct file *open_exec(const char *name)
674 err = inode_permission(nd.path.dentry->d_inode, MAY_EXEC | MAY_OPEN); 678 err = inode_permission(nd.path.dentry->d_inode, MAY_EXEC | MAY_OPEN);
675 if (err) 679 if (err)
676 goto out_path_put; 680 goto out_path_put;
681 err = ima_path_check(&nd.path, MAY_EXEC | MAY_OPEN);
682 if (err)
683 goto out_path_put;
677 684
678 file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE); 685 file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
679 if (IS_ERR(file)) 686 if (IS_ERR(file))
@@ -1049,16 +1056,32 @@ EXPORT_SYMBOL(install_exec_creds);
1049 * - the caller must hold current->cred_exec_mutex to protect against 1056 * - the caller must hold current->cred_exec_mutex to protect against
1050 * PTRACE_ATTACH 1057 * PTRACE_ATTACH
1051 */ 1058 */
1052void check_unsafe_exec(struct linux_binprm *bprm) 1059void check_unsafe_exec(struct linux_binprm *bprm, struct files_struct *files)
1053{ 1060{
1054 struct task_struct *p = current; 1061 struct task_struct *p = current, *t;
1062 unsigned long flags;
1063 unsigned n_fs, n_files, n_sighand;
1055 1064
1056 bprm->unsafe = tracehook_unsafe_exec(p); 1065 bprm->unsafe = tracehook_unsafe_exec(p);
1057 1066
1058 if (atomic_read(&p->fs->count) > 1 || 1067 n_fs = 1;
1059 atomic_read(&p->files->count) > 1 || 1068 n_files = 1;
1060 atomic_read(&p->sighand->count) > 1) 1069 n_sighand = 1;
1070 lock_task_sighand(p, &flags);
1071 for (t = next_thread(p); t != p; t = next_thread(t)) {
1072 if (t->fs == p->fs)
1073 n_fs++;
1074 if (t->files == files)
1075 n_files++;
1076 n_sighand++;
1077 }
1078
1079 if (atomic_read(&p->fs->count) > n_fs ||
1080 atomic_read(&p->files->count) > n_files ||
1081 atomic_read(&p->sighand->count) > n_sighand)
1061 bprm->unsafe |= LSM_UNSAFE_SHARE; 1082 bprm->unsafe |= LSM_UNSAFE_SHARE;
1083
1084 unlock_task_sighand(p, &flags);
1062} 1085}
1063 1086
1064/* 1087/*
@@ -1168,6 +1191,9 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
1168 retval = security_bprm_check(bprm); 1191 retval = security_bprm_check(bprm);
1169 if (retval) 1192 if (retval)
1170 return retval; 1193 return retval;
1194 retval = ima_bprm_check(bprm);
1195 if (retval)
1196 return retval;
1171 1197
1172 /* kernel module loader fixup */ 1198 /* kernel module loader fixup */
1173 /* so we don't try to load run modprobe in kernel space. */ 1199 /* so we don't try to load run modprobe in kernel space. */
@@ -1268,12 +1294,13 @@ int do_execve(char * filename,
1268 retval = mutex_lock_interruptible(&current->cred_exec_mutex); 1294 retval = mutex_lock_interruptible(&current->cred_exec_mutex);
1269 if (retval < 0) 1295 if (retval < 0)
1270 goto out_free; 1296 goto out_free;
1297 current->in_execve = 1;
1271 1298
1272 retval = -ENOMEM; 1299 retval = -ENOMEM;
1273 bprm->cred = prepare_exec_creds(); 1300 bprm->cred = prepare_exec_creds();
1274 if (!bprm->cred) 1301 if (!bprm->cred)
1275 goto out_unlock; 1302 goto out_unlock;
1276 check_unsafe_exec(bprm); 1303 check_unsafe_exec(bprm, displaced);
1277 1304
1278 file = open_exec(filename); 1305 file = open_exec(filename);
1279 retval = PTR_ERR(file); 1306 retval = PTR_ERR(file);
@@ -1321,6 +1348,7 @@ int do_execve(char * filename,
1321 goto out; 1348 goto out;
1322 1349
1323 /* execve succeeded */ 1350 /* execve succeeded */
1351 current->in_execve = 0;
1324 mutex_unlock(&current->cred_exec_mutex); 1352 mutex_unlock(&current->cred_exec_mutex);
1325 acct_update_integrals(current); 1353 acct_update_integrals(current);
1326 free_bprm(bprm); 1354 free_bprm(bprm);
@@ -1339,6 +1367,7 @@ out_file:
1339 } 1367 }
1340 1368
1341out_unlock: 1369out_unlock:
1370 current->in_execve = 0;
1342 mutex_unlock(&current->cred_exec_mutex); 1371 mutex_unlock(&current->cred_exec_mutex);
1343 1372
1344out_free: 1373out_free: