aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2005-06-23 03:09:43 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-23 12:45:26 -0400
commitd6e711448137ca3301512cec41a2c2ce852b3d0a (patch)
treef0765ebd90fdbdf270c05fcd7f3d32b24ba56681 /kernel
parent8b0914ea7475615c7c8965c1ac8fe4069270f25c (diff)
[PATCH] setuid core dump
Add a new `suid_dumpable' sysctl: This value can be used to query and set the core dump mode for setuid or otherwise protected/tainted binaries. The modes are 0 - (default) - traditional behaviour. Any process which has changed privilege levels or is execute only will not be dumped 1 - (debug) - all processes dump core when possible. The core dump is owned by the current user and no security is applied. This is intended for system debugging situations only. Ptrace is unchecked. 2 - (suidsafe) - any binary which normally would not be dumped is dumped readable by root only. This allows the end user to remove such a dump but not access it directly. For security reasons core dumps in this mode will not overwrite one another or other files. This mode is appropriate when adminstrators are attempting to debug problems in a normal environment. (akpm: > > +EXPORT_SYMBOL(suid_dumpable); > > EXPORT_SYMBOL_GPL? No problem to me. > > if (current->euid == current->uid && current->egid == current->gid) > > current->mm->dumpable = 1; > > Should this be SUID_DUMP_USER? Actually the feedback I had from last time was that the SUID_ defines should go because its clearer to follow the numbers. They can go everywhere (and there are lots of places where dumpable is tested/used as a bool in untouched code) > Maybe this should be renamed to `dump_policy' or something. Doing that > would help us catch any code which isn't using the #defines, too. Fair comment. The patch was designed to be easy to maintain for Red Hat rather than for merging. Changing that field would create a gigantic diff because it is used all over the place. ) Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sys.c22
-rw-r--r--kernel/sysctl.c9
2 files changed, 20 insertions, 11 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index f006632c2ba7..0a2c8cda9638 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -525,7 +525,7 @@ asmlinkage long sys_setregid(gid_t rgid, gid_t egid)
525 } 525 }
526 if (new_egid != old_egid) 526 if (new_egid != old_egid)
527 { 527 {
528 current->mm->dumpable = 0; 528 current->mm->dumpable = suid_dumpable;
529 smp_wmb(); 529 smp_wmb();
530 } 530 }
531 if (rgid != (gid_t) -1 || 531 if (rgid != (gid_t) -1 ||
@@ -556,7 +556,7 @@ asmlinkage long sys_setgid(gid_t gid)
556 { 556 {
557 if(old_egid != gid) 557 if(old_egid != gid)
558 { 558 {
559 current->mm->dumpable=0; 559 current->mm->dumpable = suid_dumpable;
560 smp_wmb(); 560 smp_wmb();
561 } 561 }
562 current->gid = current->egid = current->sgid = current->fsgid = gid; 562 current->gid = current->egid = current->sgid = current->fsgid = gid;
@@ -565,7 +565,7 @@ asmlinkage long sys_setgid(gid_t gid)
565 { 565 {
566 if(old_egid != gid) 566 if(old_egid != gid)
567 { 567 {
568 current->mm->dumpable=0; 568 current->mm->dumpable = suid_dumpable;
569 smp_wmb(); 569 smp_wmb();
570 } 570 }
571 current->egid = current->fsgid = gid; 571 current->egid = current->fsgid = gid;
@@ -596,7 +596,7 @@ static int set_user(uid_t new_ruid, int dumpclear)
596 596
597 if(dumpclear) 597 if(dumpclear)
598 { 598 {
599 current->mm->dumpable = 0; 599 current->mm->dumpable = suid_dumpable;
600 smp_wmb(); 600 smp_wmb();
601 } 601 }
602 current->uid = new_ruid; 602 current->uid = new_ruid;
@@ -653,7 +653,7 @@ asmlinkage long sys_setreuid(uid_t ruid, uid_t euid)
653 653
654 if (new_euid != old_euid) 654 if (new_euid != old_euid)
655 { 655 {
656 current->mm->dumpable=0; 656 current->mm->dumpable = suid_dumpable;
657 smp_wmb(); 657 smp_wmb();
658 } 658 }
659 current->fsuid = current->euid = new_euid; 659 current->fsuid = current->euid = new_euid;
@@ -703,7 +703,7 @@ asmlinkage long sys_setuid(uid_t uid)
703 703
704 if (old_euid != uid) 704 if (old_euid != uid)
705 { 705 {
706 current->mm->dumpable = 0; 706 current->mm->dumpable = suid_dumpable;
707 smp_wmb(); 707 smp_wmb();
708 } 708 }
709 current->fsuid = current->euid = uid; 709 current->fsuid = current->euid = uid;
@@ -748,7 +748,7 @@ asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
748 if (euid != (uid_t) -1) { 748 if (euid != (uid_t) -1) {
749 if (euid != current->euid) 749 if (euid != current->euid)
750 { 750 {
751 current->mm->dumpable = 0; 751 current->mm->dumpable = suid_dumpable;
752 smp_wmb(); 752 smp_wmb();
753 } 753 }
754 current->euid = euid; 754 current->euid = euid;
@@ -798,7 +798,7 @@ asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
798 if (egid != (gid_t) -1) { 798 if (egid != (gid_t) -1) {
799 if (egid != current->egid) 799 if (egid != current->egid)
800 { 800 {
801 current->mm->dumpable = 0; 801 current->mm->dumpable = suid_dumpable;
802 smp_wmb(); 802 smp_wmb();
803 } 803 }
804 current->egid = egid; 804 current->egid = egid;
@@ -845,7 +845,7 @@ asmlinkage long sys_setfsuid(uid_t uid)
845 { 845 {
846 if (uid != old_fsuid) 846 if (uid != old_fsuid)
847 { 847 {
848 current->mm->dumpable = 0; 848 current->mm->dumpable = suid_dumpable;
849 smp_wmb(); 849 smp_wmb();
850 } 850 }
851 current->fsuid = uid; 851 current->fsuid = uid;
@@ -875,7 +875,7 @@ asmlinkage long sys_setfsgid(gid_t gid)
875 { 875 {
876 if (gid != old_fsgid) 876 if (gid != old_fsgid)
877 { 877 {
878 current->mm->dumpable = 0; 878 current->mm->dumpable = suid_dumpable;
879 smp_wmb(); 879 smp_wmb();
880 } 880 }
881 current->fsgid = gid; 881 current->fsgid = gid;
@@ -1652,7 +1652,7 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
1652 error = 1; 1652 error = 1;
1653 break; 1653 break;
1654 case PR_SET_DUMPABLE: 1654 case PR_SET_DUMPABLE:
1655 if (arg2 != 0 && arg2 != 1) { 1655 if (arg2 < 0 || arg2 > 2) {
1656 error = -EINVAL; 1656 error = -EINVAL;
1657 break; 1657 break;
1658 } 1658 }
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 701d12c63068..24a4d12d5aa9 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -58,6 +58,7 @@ extern int sysctl_overcommit_ratio;
58extern int max_threads; 58extern int max_threads;
59extern int sysrq_enabled; 59extern int sysrq_enabled;
60extern int core_uses_pid; 60extern int core_uses_pid;
61extern int suid_dumpable;
61extern char core_pattern[]; 62extern char core_pattern[];
62extern int cad_pid; 63extern int cad_pid;
63extern int pid_max; 64extern int pid_max;
@@ -950,6 +951,14 @@ static ctl_table fs_table[] = {
950 .proc_handler = &proc_dointvec, 951 .proc_handler = &proc_dointvec,
951 }, 952 },
952#endif 953#endif
954 {
955 .ctl_name = KERN_SETUID_DUMPABLE,
956 .procname = "suid_dumpable",
957 .data = &suid_dumpable,
958 .maxlen = sizeof(int),
959 .mode = 0644,
960 .proc_handler = &proc_dointvec,
961 },
953 { .ctl_name = 0 } 962 { .ctl_name = 0 }
954}; 963};
955 964