aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c78
1 files changed, 50 insertions, 28 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 895823d0149d..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>
@@ -677,8 +678,8 @@ exit:
677} 678}
678EXPORT_SYMBOL(open_exec); 679EXPORT_SYMBOL(open_exec);
679 680
680int kernel_read(struct file *file, unsigned long offset, 681int kernel_read(struct file *file, loff_t offset,
681 char *addr, unsigned long count) 682 char *addr, unsigned long count)
682{ 683{
683 mm_segment_t old_fs; 684 mm_segment_t old_fs;
684 loff_t pos = offset; 685 loff_t pos = offset;
@@ -922,6 +923,7 @@ void set_task_comm(struct task_struct *tsk, char *buf)
922 task_lock(tsk); 923 task_lock(tsk);
923 strlcpy(tsk->comm, buf, sizeof(tsk->comm)); 924 strlcpy(tsk->comm, buf, sizeof(tsk->comm));
924 task_unlock(tsk); 925 task_unlock(tsk);
926 perf_counter_comm(tsk);
925} 927}
926 928
927int flush_old_exec(struct linux_binprm * bprm) 929int flush_old_exec(struct linux_binprm * bprm)
@@ -990,6 +992,13 @@ int flush_old_exec(struct linux_binprm * bprm)
990 992
991 current->personality &= ~bprm->per_clear; 993 current->personality &= ~bprm->per_clear;
992 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
993 /* 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
994 group */ 1003 group */
995 1004
@@ -1007,6 +1016,35 @@ out:
1007EXPORT_SYMBOL(flush_old_exec); 1016EXPORT_SYMBOL(flush_old_exec);
1008 1017
1009/* 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/*
1010 * install the new credentials for this executable 1048 * install the new credentials for this executable
1011 */ 1049 */
1012void install_exec_creds(struct linux_binprm *bprm) 1050void install_exec_creds(struct linux_binprm *bprm)
@@ -1015,18 +1053,19 @@ void install_exec_creds(struct linux_binprm *bprm)
1015 1053
1016 commit_creds(bprm->cred); 1054 commit_creds(bprm->cred);
1017 bprm->cred = NULL; 1055 bprm->cred = NULL;
1018 1056 /*
1019 /* 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
1020 * ptrace_attach() from altering our determination of the task's 1058 * ptrace_attach() from altering our determination of the task's
1021 * credentials; any time after this it may be unlocked */ 1059 * credentials; any time after this it may be unlocked.
1022 1060 */
1023 security_bprm_committed_creds(bprm); 1061 security_bprm_committed_creds(bprm);
1062 mutex_unlock(&current->cred_guard_mutex);
1024} 1063}
1025EXPORT_SYMBOL(install_exec_creds); 1064EXPORT_SYMBOL(install_exec_creds);
1026 1065
1027/* 1066/*
1028 * determine how safe it is to execute the proposed program 1067 * determine how safe it is to execute the proposed program
1029 * - the caller must hold current->cred_exec_mutex to protect against 1068 * - the caller must hold current->cred_guard_mutex to protect against
1030 * PTRACE_ATTACH 1069 * PTRACE_ATTACH
1031 */ 1070 */
1032int check_unsafe_exec(struct linux_binprm *bprm) 1071int check_unsafe_exec(struct linux_binprm *bprm)
@@ -1237,14 +1276,6 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
1237 1276
1238EXPORT_SYMBOL(search_binary_handler); 1277EXPORT_SYMBOL(search_binary_handler);
1239 1278
1240void free_bprm(struct linux_binprm *bprm)
1241{
1242 free_arg_pages(bprm);
1243 if (bprm->cred)
1244 abort_creds(bprm->cred);
1245 kfree(bprm);
1246}
1247
1248/* 1279/*
1249 * sys_execve() executes a new program. 1280 * sys_execve() executes a new program.
1250 */ 1281 */
@@ -1268,20 +1299,15 @@ int do_execve(char * filename,
1268 if (!bprm) 1299 if (!bprm)
1269 goto out_files; 1300 goto out_files;
1270 1301
1271 retval = mutex_lock_interruptible(&current->cred_exec_mutex); 1302 retval = prepare_bprm_creds(bprm);
1272 if (retval < 0) 1303 if (retval)
1273 goto out_free; 1304 goto out_free;
1274 current->in_execve = 1;
1275
1276 retval = -ENOMEM;
1277 bprm->cred = prepare_exec_creds();
1278 if (!bprm->cred)
1279 goto out_unlock;
1280 1305
1281 retval = check_unsafe_exec(bprm); 1306 retval = check_unsafe_exec(bprm);
1282 if (retval < 0) 1307 if (retval < 0)
1283 goto out_unlock; 1308 goto out_free;
1284 clear_in_exec = retval; 1309 clear_in_exec = retval;
1310 current->in_execve = 1;
1285 1311
1286 file = open_exec(filename); 1312 file = open_exec(filename);
1287 retval = PTR_ERR(file); 1313 retval = PTR_ERR(file);
@@ -1331,7 +1357,6 @@ int do_execve(char * filename,
1331 /* execve succeeded */ 1357 /* execve succeeded */
1332 current->fs->in_exec = 0; 1358 current->fs->in_exec = 0;
1333 current->in_execve = 0; 1359 current->in_execve = 0;
1334 mutex_unlock(&current->cred_exec_mutex);
1335 acct_update_integrals(current); 1360 acct_update_integrals(current);
1336 free_bprm(bprm); 1361 free_bprm(bprm);
1337 if (displaced) 1362 if (displaced)
@@ -1351,10 +1376,7 @@ out_file:
1351out_unmark: 1376out_unmark:
1352 if (clear_in_exec) 1377 if (clear_in_exec)
1353 current->fs->in_exec = 0; 1378 current->fs->in_exec = 0;
1354
1355out_unlock:
1356 current->in_execve = 0; 1379 current->in_execve = 0;
1357 mutex_unlock(&current->cred_exec_mutex);
1358 1380
1359out_free: 1381out_free:
1360 free_bprm(bprm); 1382 free_bprm(bprm);