aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-04-06 03:02:57 -0400
committerIngo Molnar <mingo@elte.hu>2009-04-06 03:02:57 -0400
commitf541ae326fa120fa5c57433e4d9a133df212ce41 (patch)
treebdbd94ec72cfc601118051cb35e8617d55510177 /fs/exec.c
parente255357764f92afcafafbd4879b222b8c752065a (diff)
parent0221c81b1b8eb0cbb6b30a0ced52ead32d2b4e4c (diff)
Merge branch 'linus' into perfcounters/core-v2
Merge reason: we have gathered quite a few conflicts, need to merge upstream Conflicts: arch/powerpc/kernel/Makefile arch/x86/ia32/ia32entry.S arch/x86/include/asm/hardirq.h arch/x86/include/asm/unistd_32.h arch/x86/include/asm/unistd_64.h arch/x86/kernel/cpu/common.c arch/x86/kernel/irq.c arch/x86/kernel/syscall_table_32.S arch/x86/mm/iomap_32.c include/linux/sched.h kernel/Makefile Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c52
1 files changed, 40 insertions, 12 deletions
diff --git a/fs/exec.c b/fs/exec.c
index af1600cfa8c9..e015c0b5a082 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -46,6 +46,7 @@
46#include <linux/proc_fs.h> 46#include <linux/proc_fs.h>
47#include <linux/mount.h> 47#include <linux/mount.h>
48#include <linux/security.h> 48#include <linux/security.h>
49#include <linux/ima.h>
49#include <linux/syscalls.h> 50#include <linux/syscalls.h>
50#include <linux/tsacct_kern.h> 51#include <linux/tsacct_kern.h>
51#include <linux/cn_proc.h> 52#include <linux/cn_proc.h>
@@ -53,6 +54,7 @@
53#include <linux/tracehook.h> 54#include <linux/tracehook.h>
54#include <linux/kmod.h> 55#include <linux/kmod.h>
55#include <linux/fsnotify.h> 56#include <linux/fsnotify.h>
57#include <linux/fs_struct.h>
56 58
57#include <asm/uaccess.h> 59#include <asm/uaccess.h>
58#include <asm/mmu_context.h> 60#include <asm/mmu_context.h>
@@ -128,6 +130,9 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
128 MAY_READ | MAY_EXEC | MAY_OPEN); 130 MAY_READ | MAY_EXEC | MAY_OPEN);
129 if (error) 131 if (error)
130 goto exit; 132 goto exit;
133 error = ima_path_check(&nd.path, MAY_READ | MAY_EXEC | MAY_OPEN);
134 if (error)
135 goto exit;
131 136
132 file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE); 137 file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
133 error = PTR_ERR(file); 138 error = PTR_ERR(file);
@@ -675,6 +680,9 @@ struct file *open_exec(const char *name)
675 err = inode_permission(nd.path.dentry->d_inode, MAY_EXEC | MAY_OPEN); 680 err = inode_permission(nd.path.dentry->d_inode, MAY_EXEC | MAY_OPEN);
676 if (err) 681 if (err)
677 goto out_path_put; 682 goto out_path_put;
683 err = ima_path_check(&nd.path, MAY_EXEC | MAY_OPEN);
684 if (err)
685 goto out_path_put;
678 686
679 file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE); 687 file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
680 if (IS_ERR(file)) 688 if (IS_ERR(file))
@@ -1057,32 +1065,35 @@ EXPORT_SYMBOL(install_exec_creds);
1057 * - the caller must hold current->cred_exec_mutex to protect against 1065 * - the caller must hold current->cred_exec_mutex to protect against
1058 * PTRACE_ATTACH 1066 * PTRACE_ATTACH
1059 */ 1067 */
1060void check_unsafe_exec(struct linux_binprm *bprm, struct files_struct *files) 1068int check_unsafe_exec(struct linux_binprm *bprm)
1061{ 1069{
1062 struct task_struct *p = current, *t; 1070 struct task_struct *p = current, *t;
1063 unsigned long flags; 1071 unsigned long flags;
1064 unsigned n_fs, n_files, n_sighand; 1072 unsigned n_fs;
1073 int res = 0;
1065 1074
1066 bprm->unsafe = tracehook_unsafe_exec(p); 1075 bprm->unsafe = tracehook_unsafe_exec(p);
1067 1076
1068 n_fs = 1; 1077 n_fs = 1;
1069 n_files = 1; 1078 write_lock(&p->fs->lock);
1070 n_sighand = 1;
1071 lock_task_sighand(p, &flags); 1079 lock_task_sighand(p, &flags);
1072 for (t = next_thread(p); t != p; t = next_thread(t)) { 1080 for (t = next_thread(p); t != p; t = next_thread(t)) {
1073 if (t->fs == p->fs) 1081 if (t->fs == p->fs)
1074 n_fs++; 1082 n_fs++;
1075 if (t->files == files)
1076 n_files++;
1077 n_sighand++;
1078 } 1083 }
1079 1084
1080 if (atomic_read(&p->fs->count) > n_fs || 1085 if (p->fs->users > n_fs) {
1081 atomic_read(&p->files->count) > n_files ||
1082 atomic_read(&p->sighand->count) > n_sighand)
1083 bprm->unsafe |= LSM_UNSAFE_SHARE; 1086 bprm->unsafe |= LSM_UNSAFE_SHARE;
1087 } else {
1088 if (p->fs->in_exec)
1089 res = -EAGAIN;
1090 p->fs->in_exec = 1;
1091 }
1084 1092
1085 unlock_task_sighand(p, &flags); 1093 unlock_task_sighand(p, &flags);
1094 write_unlock(&p->fs->lock);
1095
1096 return res;
1086} 1097}
1087 1098
1088/* 1099/*
@@ -1192,6 +1203,9 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
1192 retval = security_bprm_check(bprm); 1203 retval = security_bprm_check(bprm);
1193 if (retval) 1204 if (retval)
1194 return retval; 1205 return retval;
1206 retval = ima_bprm_check(bprm);
1207 if (retval)
1208 return retval;
1195 1209
1196 /* kernel module loader fixup */ 1210 /* kernel module loader fixup */
1197 /* so we don't try to load run modprobe in kernel space. */ 1211 /* so we don't try to load run modprobe in kernel space. */
@@ -1292,17 +1306,21 @@ int do_execve(char * filename,
1292 retval = mutex_lock_interruptible(&current->cred_exec_mutex); 1306 retval = mutex_lock_interruptible(&current->cred_exec_mutex);
1293 if (retval < 0) 1307 if (retval < 0)
1294 goto out_free; 1308 goto out_free;
1309 current->in_execve = 1;
1295 1310
1296 retval = -ENOMEM; 1311 retval = -ENOMEM;
1297 bprm->cred = prepare_exec_creds(); 1312 bprm->cred = prepare_exec_creds();
1298 if (!bprm->cred) 1313 if (!bprm->cred)
1299 goto out_unlock; 1314 goto out_unlock;
1300 check_unsafe_exec(bprm, displaced); 1315
1316 retval = check_unsafe_exec(bprm);
1317 if (retval)
1318 goto out_unlock;
1301 1319
1302 file = open_exec(filename); 1320 file = open_exec(filename);
1303 retval = PTR_ERR(file); 1321 retval = PTR_ERR(file);
1304 if (IS_ERR(file)) 1322 if (IS_ERR(file))
1305 goto out_unlock; 1323 goto out_unmark;
1306 1324
1307 sched_exec(); 1325 sched_exec();
1308 1326
@@ -1345,6 +1363,10 @@ int do_execve(char * filename,
1345 goto out; 1363 goto out;
1346 1364
1347 /* execve succeeded */ 1365 /* execve succeeded */
1366 write_lock(&current->fs->lock);
1367 current->fs->in_exec = 0;
1368 write_unlock(&current->fs->lock);
1369 current->in_execve = 0;
1348 mutex_unlock(&current->cred_exec_mutex); 1370 mutex_unlock(&current->cred_exec_mutex);
1349 acct_update_integrals(current); 1371 acct_update_integrals(current);
1350 free_bprm(bprm); 1372 free_bprm(bprm);
@@ -1362,7 +1384,13 @@ out_file:
1362 fput(bprm->file); 1384 fput(bprm->file);
1363 } 1385 }
1364 1386
1387out_unmark:
1388 write_lock(&current->fs->lock);
1389 current->fs->in_exec = 0;
1390 write_unlock(&current->fs->lock);
1391
1365out_unlock: 1392out_unlock:
1393 current->in_execve = 0;
1366 mutex_unlock(&current->cred_exec_mutex); 1394 mutex_unlock(&current->cred_exec_mutex);
1367 1395
1368out_free: 1396out_free: