aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c206
1 files changed, 124 insertions, 82 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 4e834f16d9da..dfbf7009fbe7 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -55,6 +55,7 @@
55#include <asm/uaccess.h> 55#include <asm/uaccess.h>
56#include <asm/mmu_context.h> 56#include <asm/mmu_context.h>
57#include <asm/tlb.h> 57#include <asm/tlb.h>
58#include "internal.h"
58 59
59#ifdef __alpha__ 60#ifdef __alpha__
60/* for /sbin/loader handling in search_binary_handler() */ 61/* for /sbin/loader handling in search_binary_handler() */
@@ -126,7 +127,8 @@ asmlinkage long sys_uselib(const char __user * library)
126 if (nd.path.mnt->mnt_flags & MNT_NOEXEC) 127 if (nd.path.mnt->mnt_flags & MNT_NOEXEC)
127 goto exit; 128 goto exit;
128 129
129 error = vfs_permission(&nd, MAY_READ | MAY_EXEC | MAY_OPEN); 130 error = inode_permission(nd.path.dentry->d_inode,
131 MAY_READ | MAY_EXEC | MAY_OPEN);
130 if (error) 132 if (error)
131 goto exit; 133 goto exit;
132 134
@@ -679,7 +681,7 @@ struct file *open_exec(const char *name)
679 if (nd.path.mnt->mnt_flags & MNT_NOEXEC) 681 if (nd.path.mnt->mnt_flags & MNT_NOEXEC)
680 goto out_path_put; 682 goto out_path_put;
681 683
682 err = vfs_permission(&nd, MAY_EXEC | MAY_OPEN); 684 err = inode_permission(nd.path.dentry->d_inode, MAY_EXEC | MAY_OPEN);
683 if (err) 685 if (err)
684 goto out_path_put; 686 goto out_path_put;
685 687
@@ -772,7 +774,6 @@ static int de_thread(struct task_struct *tsk)
772 struct signal_struct *sig = tsk->signal; 774 struct signal_struct *sig = tsk->signal;
773 struct sighand_struct *oldsighand = tsk->sighand; 775 struct sighand_struct *oldsighand = tsk->sighand;
774 spinlock_t *lock = &oldsighand->siglock; 776 spinlock_t *lock = &oldsighand->siglock;
775 struct task_struct *leader = NULL;
776 int count; 777 int count;
777 778
778 if (thread_group_empty(tsk)) 779 if (thread_group_empty(tsk))
@@ -810,7 +811,7 @@ static int de_thread(struct task_struct *tsk)
810 * and to assume its PID: 811 * and to assume its PID:
811 */ 812 */
812 if (!thread_group_leader(tsk)) { 813 if (!thread_group_leader(tsk)) {
813 leader = tsk->group_leader; 814 struct task_struct *leader = tsk->group_leader;
814 815
815 sig->notify_count = -1; /* for exit_notify() */ 816 sig->notify_count = -1; /* for exit_notify() */
816 for (;;) { 817 for (;;) {
@@ -862,8 +863,9 @@ static int de_thread(struct task_struct *tsk)
862 863
863 BUG_ON(leader->exit_state != EXIT_ZOMBIE); 864 BUG_ON(leader->exit_state != EXIT_ZOMBIE);
864 leader->exit_state = EXIT_DEAD; 865 leader->exit_state = EXIT_DEAD;
865
866 write_unlock_irq(&tasklist_lock); 866 write_unlock_irq(&tasklist_lock);
867
868 release_task(leader);
867 } 869 }
868 870
869 sig->group_exit_task = NULL; 871 sig->group_exit_task = NULL;
@@ -872,8 +874,6 @@ static int de_thread(struct task_struct *tsk)
872no_thread_group: 874no_thread_group:
873 exit_itimers(sig); 875 exit_itimers(sig);
874 flush_itimer_signals(); 876 flush_itimer_signals();
875 if (leader)
876 release_task(leader);
877 877
878 if (atomic_read(&oldsighand->count) != 1) { 878 if (atomic_read(&oldsighand->count) != 1) {
879 struct sighand_struct *newsighand; 879 struct sighand_struct *newsighand;
@@ -980,7 +980,7 @@ int flush_old_exec(struct linux_binprm * bprm)
980 /* This is the point of no return */ 980 /* This is the point of no return */
981 current->sas_ss_sp = current->sas_ss_size = 0; 981 current->sas_ss_sp = current->sas_ss_size = 0;
982 982
983 if (current->euid == current->uid && current->egid == current->gid) 983 if (current_euid() == current_uid() && current_egid() == current_gid())
984 set_dumpable(current->mm, 1); 984 set_dumpable(current->mm, 1);
985 else 985 else
986 set_dumpable(current->mm, suid_dumpable); 986 set_dumpable(current->mm, suid_dumpable);
@@ -1007,16 +1007,17 @@ int flush_old_exec(struct linux_binprm * bprm)
1007 */ 1007 */
1008 current->mm->task_size = TASK_SIZE; 1008 current->mm->task_size = TASK_SIZE;
1009 1009
1010 if (bprm->e_uid != current->euid || bprm->e_gid != current->egid) { 1010 /* install the new credentials */
1011 suid_keys(current); 1011 if (bprm->cred->uid != current_euid() ||
1012 set_dumpable(current->mm, suid_dumpable); 1012 bprm->cred->gid != current_egid()) {
1013 current->pdeath_signal = 0; 1013 current->pdeath_signal = 0;
1014 } else if (file_permission(bprm->file, MAY_READ) || 1014 } else if (file_permission(bprm->file, MAY_READ) ||
1015 (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) { 1015 bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP) {
1016 suid_keys(current);
1017 set_dumpable(current->mm, suid_dumpable); 1016 set_dumpable(current->mm, suid_dumpable);
1018 } 1017 }
1019 1018
1019 current->personality &= ~bprm->per_clear;
1020
1020 /* An exec changes our domain. We are no longer part of the thread 1021 /* An exec changes our domain. We are no longer part of the thread
1021 group */ 1022 group */
1022 1023
@@ -1033,13 +1034,50 @@ out:
1033 1034
1034EXPORT_SYMBOL(flush_old_exec); 1035EXPORT_SYMBOL(flush_old_exec);
1035 1036
1037/*
1038 * install the new credentials for this executable
1039 */
1040void install_exec_creds(struct linux_binprm *bprm)
1041{
1042 security_bprm_committing_creds(bprm);
1043
1044 commit_creds(bprm->cred);
1045 bprm->cred = NULL;
1046
1047 /* cred_exec_mutex must be held at least to this point to prevent
1048 * ptrace_attach() from altering our determination of the task's
1049 * credentials; any time after this it may be unlocked */
1050
1051 security_bprm_committed_creds(bprm);
1052}
1053EXPORT_SYMBOL(install_exec_creds);
1054
1055/*
1056 * determine how safe it is to execute the proposed program
1057 * - the caller must hold current->cred_exec_mutex to protect against
1058 * PTRACE_ATTACH
1059 */
1060void check_unsafe_exec(struct linux_binprm *bprm)
1061{
1062 struct task_struct *p = current;
1063
1064 bprm->unsafe = tracehook_unsafe_exec(p);
1065
1066 if (atomic_read(&p->fs->count) > 1 ||
1067 atomic_read(&p->files->count) > 1 ||
1068 atomic_read(&p->sighand->count) > 1)
1069 bprm->unsafe |= LSM_UNSAFE_SHARE;
1070}
1071
1036/* 1072/*
1037 * Fill the binprm structure from the inode. 1073 * Fill the binprm structure from the inode.
1038 * Check permissions, then read the first 128 (BINPRM_BUF_SIZE) bytes 1074 * Check permissions, then read the first 128 (BINPRM_BUF_SIZE) bytes
1075 *
1076 * This may be called multiple times for binary chains (scripts for example).
1039 */ 1077 */
1040int prepare_binprm(struct linux_binprm *bprm) 1078int prepare_binprm(struct linux_binprm *bprm)
1041{ 1079{
1042 int mode; 1080 umode_t mode;
1043 struct inode * inode = bprm->file->f_path.dentry->d_inode; 1081 struct inode * inode = bprm->file->f_path.dentry->d_inode;
1044 int retval; 1082 int retval;
1045 1083
@@ -1047,14 +1085,15 @@ int prepare_binprm(struct linux_binprm *bprm)
1047 if (bprm->file->f_op == NULL) 1085 if (bprm->file->f_op == NULL)
1048 return -EACCES; 1086 return -EACCES;
1049 1087
1050 bprm->e_uid = current->euid; 1088 /* clear any previous set[ug]id data from a previous binary */
1051 bprm->e_gid = current->egid; 1089 bprm->cred->euid = current_euid();
1090 bprm->cred->egid = current_egid();
1052 1091
1053 if(!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)) { 1092 if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)) {
1054 /* Set-uid? */ 1093 /* Set-uid? */
1055 if (mode & S_ISUID) { 1094 if (mode & S_ISUID) {
1056 current->personality &= ~PER_CLEAR_ON_SETID; 1095 bprm->per_clear |= PER_CLEAR_ON_SETID;
1057 bprm->e_uid = inode->i_uid; 1096 bprm->cred->euid = inode->i_uid;
1058 } 1097 }
1059 1098
1060 /* Set-gid? */ 1099 /* Set-gid? */
@@ -1064,52 +1103,23 @@ int prepare_binprm(struct linux_binprm *bprm)
1064 * executable. 1103 * executable.
1065 */ 1104 */
1066 if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { 1105 if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
1067 current->personality &= ~PER_CLEAR_ON_SETID; 1106 bprm->per_clear |= PER_CLEAR_ON_SETID;
1068 bprm->e_gid = inode->i_gid; 1107 bprm->cred->egid = inode->i_gid;
1069 } 1108 }
1070 } 1109 }
1071 1110
1072 /* fill in binprm security blob */ 1111 /* fill in binprm security blob */
1073 retval = security_bprm_set(bprm); 1112 retval = security_bprm_set_creds(bprm);
1074 if (retval) 1113 if (retval)
1075 return retval; 1114 return retval;
1115 bprm->cred_prepared = 1;
1076 1116
1077 memset(bprm->buf,0,BINPRM_BUF_SIZE); 1117 memset(bprm->buf, 0, BINPRM_BUF_SIZE);
1078 return kernel_read(bprm->file,0,bprm->buf,BINPRM_BUF_SIZE); 1118 return kernel_read(bprm->file, 0, bprm->buf, BINPRM_BUF_SIZE);
1079} 1119}
1080 1120
1081EXPORT_SYMBOL(prepare_binprm); 1121EXPORT_SYMBOL(prepare_binprm);
1082 1122
1083static int unsafe_exec(struct task_struct *p)
1084{
1085 int unsafe = tracehook_unsafe_exec(p);
1086
1087 if (atomic_read(&p->fs->count) > 1 ||
1088 atomic_read(&p->files->count) > 1 ||
1089 atomic_read(&p->sighand->count) > 1)
1090 unsafe |= LSM_UNSAFE_SHARE;
1091
1092 return unsafe;
1093}
1094
1095void compute_creds(struct linux_binprm *bprm)
1096{
1097 int unsafe;
1098
1099 if (bprm->e_uid != current->uid) {
1100 suid_keys(current);
1101 current->pdeath_signal = 0;
1102 }
1103 exec_keys(current);
1104
1105 task_lock(current);
1106 unsafe = unsafe_exec(current);
1107 security_bprm_apply_creds(bprm, unsafe);
1108 task_unlock(current);
1109 security_bprm_post_apply_creds(bprm);
1110}
1111EXPORT_SYMBOL(compute_creds);
1112
1113/* 1123/*
1114 * Arguments are '\0' separated strings found at the location bprm->p 1124 * Arguments are '\0' separated strings found at the location bprm->p
1115 * points to; chop off the first by relocating brpm->p to right after 1125 * points to; chop off the first by relocating brpm->p to right after
@@ -1159,6 +1169,7 @@ EXPORT_SYMBOL(remove_arg_zero);
1159 */ 1169 */
1160int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) 1170int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
1161{ 1171{
1172 unsigned int depth = bprm->recursion_depth;
1162 int try,retval; 1173 int try,retval;
1163 struct linux_binfmt *fmt; 1174 struct linux_binfmt *fmt;
1164#ifdef __alpha__ 1175#ifdef __alpha__
@@ -1219,8 +1230,15 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
1219 continue; 1230 continue;
1220 read_unlock(&binfmt_lock); 1231 read_unlock(&binfmt_lock);
1221 retval = fn(bprm, regs); 1232 retval = fn(bprm, regs);
1233 /*
1234 * Restore the depth counter to its starting value
1235 * in this call, so we don't have to rely on every
1236 * load_binary function to restore it on return.
1237 */
1238 bprm->recursion_depth = depth;
1222 if (retval >= 0) { 1239 if (retval >= 0) {
1223 tracehook_report_exec(fmt, bprm, regs); 1240 if (depth == 0)
1241 tracehook_report_exec(fmt, bprm, regs);
1224 put_binfmt(fmt); 1242 put_binfmt(fmt);
1225 allow_write_access(bprm->file); 1243 allow_write_access(bprm->file);
1226 if (bprm->file) 1244 if (bprm->file)
@@ -1262,6 +1280,8 @@ EXPORT_SYMBOL(search_binary_handler);
1262void free_bprm(struct linux_binprm *bprm) 1280void free_bprm(struct linux_binprm *bprm)
1263{ 1281{
1264 free_arg_pages(bprm); 1282 free_arg_pages(bprm);
1283 if (bprm->cred)
1284 abort_creds(bprm->cred);
1265 kfree(bprm); 1285 kfree(bprm);
1266} 1286}
1267 1287
@@ -1287,10 +1307,20 @@ int do_execve(char * filename,
1287 if (!bprm) 1307 if (!bprm)
1288 goto out_files; 1308 goto out_files;
1289 1309
1310 retval = mutex_lock_interruptible(&current->cred_exec_mutex);
1311 if (retval < 0)
1312 goto out_free;
1313
1314 retval = -ENOMEM;
1315 bprm->cred = prepare_exec_creds();
1316 if (!bprm->cred)
1317 goto out_unlock;
1318 check_unsafe_exec(bprm);
1319
1290 file = open_exec(filename); 1320 file = open_exec(filename);
1291 retval = PTR_ERR(file); 1321 retval = PTR_ERR(file);
1292 if (IS_ERR(file)) 1322 if (IS_ERR(file))
1293 goto out_kfree; 1323 goto out_unlock;
1294 1324
1295 sched_exec(); 1325 sched_exec();
1296 1326
@@ -1304,14 +1334,10 @@ int do_execve(char * filename,
1304 1334
1305 bprm->argc = count(argv, MAX_ARG_STRINGS); 1335 bprm->argc = count(argv, MAX_ARG_STRINGS);
1306 if ((retval = bprm->argc) < 0) 1336 if ((retval = bprm->argc) < 0)
1307 goto out_mm; 1337 goto out;
1308 1338
1309 bprm->envc = count(envp, MAX_ARG_STRINGS); 1339 bprm->envc = count(envp, MAX_ARG_STRINGS);
1310 if ((retval = bprm->envc) < 0) 1340 if ((retval = bprm->envc) < 0)
1311 goto out_mm;
1312
1313 retval = security_bprm_alloc(bprm);
1314 if (retval)
1315 goto out; 1341 goto out;
1316 1342
1317 retval = prepare_binprm(bprm); 1343 retval = prepare_binprm(bprm);
@@ -1333,21 +1359,18 @@ int do_execve(char * filename,
1333 1359
1334 current->flags &= ~PF_KTHREAD; 1360 current->flags &= ~PF_KTHREAD;
1335 retval = search_binary_handler(bprm,regs); 1361 retval = search_binary_handler(bprm,regs);
1336 if (retval >= 0) { 1362 if (retval < 0)
1337 /* execve success */ 1363 goto out;
1338 security_bprm_free(bprm);
1339 acct_update_integrals(current);
1340 free_bprm(bprm);
1341 if (displaced)
1342 put_files_struct(displaced);
1343 return retval;
1344 }
1345 1364
1346out: 1365 /* execve succeeded */
1347 if (bprm->security) 1366 mutex_unlock(&current->cred_exec_mutex);
1348 security_bprm_free(bprm); 1367 acct_update_integrals(current);
1368 free_bprm(bprm);
1369 if (displaced)
1370 put_files_struct(displaced);
1371 return retval;
1349 1372
1350out_mm: 1373out:
1351 if (bprm->mm) 1374 if (bprm->mm)
1352 mmput (bprm->mm); 1375 mmput (bprm->mm);
1353 1376
@@ -1356,7 +1379,11 @@ out_file:
1356 allow_write_access(bprm->file); 1379 allow_write_access(bprm->file);
1357 fput(bprm->file); 1380 fput(bprm->file);
1358 } 1381 }
1359out_kfree: 1382
1383out_unlock:
1384 mutex_unlock(&current->cred_exec_mutex);
1385
1386out_free:
1360 free_bprm(bprm); 1387 free_bprm(bprm);
1361 1388
1362out_files: 1389out_files:
@@ -1388,6 +1415,7 @@ EXPORT_SYMBOL(set_binfmt);
1388 */ 1415 */
1389static int format_corename(char *corename, long signr) 1416static int format_corename(char *corename, long signr)
1390{ 1417{
1418 const struct cred *cred = current_cred();
1391 const char *pat_ptr = core_pattern; 1419 const char *pat_ptr = core_pattern;
1392 int ispipe = (*pat_ptr == '|'); 1420 int ispipe = (*pat_ptr == '|');
1393 char *out_ptr = corename; 1421 char *out_ptr = corename;
@@ -1424,7 +1452,7 @@ static int format_corename(char *corename, long signr)
1424 /* uid */ 1452 /* uid */
1425 case 'u': 1453 case 'u':
1426 rc = snprintf(out_ptr, out_end - out_ptr, 1454 rc = snprintf(out_ptr, out_end - out_ptr,
1427 "%d", current->uid); 1455 "%d", cred->uid);
1428 if (rc > out_end - out_ptr) 1456 if (rc > out_end - out_ptr)
1429 goto out; 1457 goto out;
1430 out_ptr += rc; 1458 out_ptr += rc;
@@ -1432,7 +1460,7 @@ static int format_corename(char *corename, long signr)
1432 /* gid */ 1460 /* gid */
1433 case 'g': 1461 case 'g':
1434 rc = snprintf(out_ptr, out_end - out_ptr, 1462 rc = snprintf(out_ptr, out_end - out_ptr,
1435 "%d", current->gid); 1463 "%d", cred->gid);
1436 if (rc > out_end - out_ptr) 1464 if (rc > out_end - out_ptr)
1437 goto out; 1465 goto out;
1438 out_ptr += rc; 1466 out_ptr += rc;
@@ -1708,8 +1736,9 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
1708 struct linux_binfmt * binfmt; 1736 struct linux_binfmt * binfmt;
1709 struct inode * inode; 1737 struct inode * inode;
1710 struct file * file; 1738 struct file * file;
1739 const struct cred *old_cred;
1740 struct cred *cred;
1711 int retval = 0; 1741 int retval = 0;
1712 int fsuid = current->fsuid;
1713 int flag = 0; 1742 int flag = 0;
1714 int ispipe = 0; 1743 int ispipe = 0;
1715 unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; 1744 unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
@@ -1722,12 +1751,20 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
1722 binfmt = current->binfmt; 1751 binfmt = current->binfmt;
1723 if (!binfmt || !binfmt->core_dump) 1752 if (!binfmt || !binfmt->core_dump)
1724 goto fail; 1753 goto fail;
1754
1755 cred = prepare_creds();
1756 if (!cred) {
1757 retval = -ENOMEM;
1758 goto fail;
1759 }
1760
1725 down_write(&mm->mmap_sem); 1761 down_write(&mm->mmap_sem);
1726 /* 1762 /*
1727 * If another thread got here first, or we are not dumpable, bail out. 1763 * If another thread got here first, or we are not dumpable, bail out.
1728 */ 1764 */
1729 if (mm->core_state || !get_dumpable(mm)) { 1765 if (mm->core_state || !get_dumpable(mm)) {
1730 up_write(&mm->mmap_sem); 1766 up_write(&mm->mmap_sem);
1767 put_cred(cred);
1731 goto fail; 1768 goto fail;
1732 } 1769 }
1733 1770
@@ -1738,12 +1775,16 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
1738 */ 1775 */
1739 if (get_dumpable(mm) == 2) { /* Setuid core dump mode */ 1776 if (get_dumpable(mm) == 2) { /* Setuid core dump mode */
1740 flag = O_EXCL; /* Stop rewrite attacks */ 1777 flag = O_EXCL; /* Stop rewrite attacks */
1741 current->fsuid = 0; /* Dump root private */ 1778 cred->fsuid = 0; /* Dump root private */
1742 } 1779 }
1743 1780
1744 retval = coredump_wait(exit_code, &core_state); 1781 retval = coredump_wait(exit_code, &core_state);
1745 if (retval < 0) 1782 if (retval < 0) {
1783 put_cred(cred);
1746 goto fail; 1784 goto fail;
1785 }
1786
1787 old_cred = override_creds(cred);
1747 1788
1748 /* 1789 /*
1749 * Clear any false indication of pending signals that might 1790 * Clear any false indication of pending signals that might
@@ -1815,7 +1856,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
1815 * Dont allow local users get cute and trick others to coredump 1856 * Dont allow local users get cute and trick others to coredump
1816 * into their pre-created files: 1857 * into their pre-created files:
1817 */ 1858 */
1818 if (inode->i_uid != current->fsuid) 1859 if (inode->i_uid != current_fsuid())
1819 goto close_fail; 1860 goto close_fail;
1820 if (!file->f_op) 1861 if (!file->f_op)
1821 goto close_fail; 1862 goto close_fail;
@@ -1834,7 +1875,8 @@ fail_unlock:
1834 if (helper_argv) 1875 if (helper_argv)
1835 argv_free(helper_argv); 1876 argv_free(helper_argv);
1836 1877
1837 current->fsuid = fsuid; 1878 revert_creds(old_cred);
1879 put_cred(cred);
1838 coredump_finish(mm); 1880 coredump_finish(mm);
1839fail: 1881fail:
1840 return retval; 1882 return retval;