aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c39
1 files changed, 27 insertions, 12 deletions
diff --git a/fs/exec.c b/fs/exec.c
index e56ee2437025..48871917d363 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -58,6 +58,9 @@
58 58
59int core_uses_pid; 59int core_uses_pid;
60char core_pattern[65] = "core"; 60char core_pattern[65] = "core";
61int suid_dumpable = 0;
62
63EXPORT_SYMBOL(suid_dumpable);
61/* The maximal length of core_pattern is also specified in sysctl.c */ 64/* The maximal length of core_pattern is also specified in sysctl.c */
62 65
63static struct linux_binfmt *formats; 66static struct linux_binfmt *formats;
@@ -649,6 +652,7 @@ static inline int de_thread(struct task_struct *tsk)
649 } 652 }
650 sig->group_exit_task = NULL; 653 sig->group_exit_task = NULL;
651 sig->notify_count = 0; 654 sig->notify_count = 0;
655 sig->real_timer.data = (unsigned long)current;
652 spin_unlock_irq(lock); 656 spin_unlock_irq(lock);
653 657
654 /* 658 /*
@@ -675,10 +679,8 @@ static inline int de_thread(struct task_struct *tsk)
675 proc_dentry2 = proc_pid_unhash(leader); 679 proc_dentry2 = proc_pid_unhash(leader);
676 write_lock_irq(&tasklist_lock); 680 write_lock_irq(&tasklist_lock);
677 681
678 if (leader->tgid != current->tgid) 682 BUG_ON(leader->tgid != current->tgid);
679 BUG(); 683 BUG_ON(current->pid == current->tgid);
680 if (current->pid == current->tgid)
681 BUG();
682 /* 684 /*
683 * An exec() starts a new thread group with the 685 * An exec() starts a new thread group with the
684 * TGID of the previous thread group. Rehash the 686 * TGID of the previous thread group. Rehash the
@@ -726,8 +728,7 @@ static inline int de_thread(struct task_struct *tsk)
726 proc_pid_flush(proc_dentry1); 728 proc_pid_flush(proc_dentry1);
727 proc_pid_flush(proc_dentry2); 729 proc_pid_flush(proc_dentry2);
728 730
729 if (exit_state != EXIT_ZOMBIE) 731 BUG_ON(exit_state != EXIT_ZOMBIE);
730 BUG();
731 release_task(leader); 732 release_task(leader);
732 } 733 }
733 734
@@ -772,10 +773,8 @@ no_thread_group:
772 kmem_cache_free(sighand_cachep, oldsighand); 773 kmem_cache_free(sighand_cachep, oldsighand);
773 } 774 }
774 775
775 if (!thread_group_empty(current)) 776 BUG_ON(!thread_group_empty(current));
776 BUG(); 777 BUG_ON(!thread_group_leader(current));
777 if (!thread_group_leader(current))
778 BUG();
779 return 0; 778 return 0;
780} 779}
781 780
@@ -868,6 +867,9 @@ int flush_old_exec(struct linux_binprm * bprm)
868 867
869 if (current->euid == current->uid && current->egid == current->gid) 868 if (current->euid == current->uid && current->egid == current->gid)
870 current->mm->dumpable = 1; 869 current->mm->dumpable = 1;
870 else
871 current->mm->dumpable = suid_dumpable;
872
871 name = bprm->filename; 873 name = bprm->filename;
872 874
873 /* Copies the binary name from after last slash */ 875 /* Copies the binary name from after last slash */
@@ -888,7 +890,7 @@ int flush_old_exec(struct linux_binprm * bprm)
888 permission(bprm->file->f_dentry->d_inode,MAY_READ, NULL) || 890 permission(bprm->file->f_dentry->d_inode,MAY_READ, NULL) ||
889 (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) { 891 (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) {
890 suid_keys(current); 892 suid_keys(current);
891 current->mm->dumpable = 0; 893 current->mm->dumpable = suid_dumpable;
892 } 894 }
893 895
894 /* An exec changes our domain. We are no longer part of the thread 896 /* An exec changes our domain. We are no longer part of the thread
@@ -1436,6 +1438,8 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
1436 struct inode * inode; 1438 struct inode * inode;
1437 struct file * file; 1439 struct file * file;
1438 int retval = 0; 1440 int retval = 0;
1441 int fsuid = current->fsuid;
1442 int flag = 0;
1439 1443
1440 binfmt = current->binfmt; 1444 binfmt = current->binfmt;
1441 if (!binfmt || !binfmt->core_dump) 1445 if (!binfmt || !binfmt->core_dump)
@@ -1445,6 +1449,16 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
1445 up_write(&mm->mmap_sem); 1449 up_write(&mm->mmap_sem);
1446 goto fail; 1450 goto fail;
1447 } 1451 }
1452
1453 /*
1454 * We cannot trust fsuid as being the "true" uid of the
1455 * process nor do we know its entire history. We only know it
1456 * was tainted so we dump it as root in mode 2.
1457 */
1458 if (mm->dumpable == 2) { /* Setuid core dump mode */
1459 flag = O_EXCL; /* Stop rewrite attacks */
1460 current->fsuid = 0; /* Dump root private */
1461 }
1448 mm->dumpable = 0; 1462 mm->dumpable = 0;
1449 init_completion(&mm->core_done); 1463 init_completion(&mm->core_done);
1450 spin_lock_irq(&current->sighand->siglock); 1464 spin_lock_irq(&current->sighand->siglock);
@@ -1470,7 +1484,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
1470 lock_kernel(); 1484 lock_kernel();
1471 format_corename(corename, core_pattern, signr); 1485 format_corename(corename, core_pattern, signr);
1472 unlock_kernel(); 1486 unlock_kernel();
1473 file = filp_open(corename, O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE, 0600); 1487 file = filp_open(corename, O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, 0600);
1474 if (IS_ERR(file)) 1488 if (IS_ERR(file))
1475 goto fail_unlock; 1489 goto fail_unlock;
1476 inode = file->f_dentry->d_inode; 1490 inode = file->f_dentry->d_inode;
@@ -1495,6 +1509,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
1495close_fail: 1509close_fail:
1496 filp_close(file, NULL); 1510 filp_close(file, NULL);
1497fail_unlock: 1511fail_unlock:
1512 current->fsuid = fsuid;
1498 complete_all(&mm->core_done); 1513 complete_all(&mm->core_done);
1499fail: 1514fail:
1500 return retval; 1515 return retval;