diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-03-23 02:25:38 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-03-23 02:25:38 +0000 |
commit | 16b5d462f73eb29d1f67fa01cc1ea66afdc72569 (patch) | |
tree | 5407bd573f4840e473ea27cbe61e5c7a07131fcd /kernel/sys.c | |
parent | ce8a076e11e7e5ee36007f9a3eee5bb3744cb8f6 (diff) |
Merge with Linux 2.3.99-pre2.
Diffstat (limited to 'kernel/sys.c')
-rw-r--r-- | kernel/sys.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/kernel/sys.c b/kernel/sys.c index 1748d8afd..6e30f0347 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -336,12 +336,23 @@ asmlinkage long sys_setgid(gid_t gid) * never happen. * * -astor + * + * cevans - New behaviour, Oct '99 + * A process may, via prctl(), elect to keep its capabilities when it + * calls setuid() and switches away from uid==0. Both permitted and + * effective sets will be retained. + * Without this change, it was impossible for a daemon to drop only some + * of its privilege. The call to setuid(!=0) would drop all privileges! + * Keeping uid 0 is not an option because uid 0 owns too many vital + * files.. + * Thanks to Olaf Kirch and Peter Benie for spotting this. */ extern inline void cap_emulate_setxuid(int old_ruid, int old_euid, int old_suid) { if ((old_ruid == 0 || old_euid == 0 || old_suid == 0) && - (current->uid != 0 && current->euid != 0 && current->suid != 0)) { + (current->uid != 0 && current->euid != 0 && current->suid != 0) && + !current->keep_capabilities) { cap_clear(current->cap_permitted); cap_clear(current->cap_effective); } @@ -1080,6 +1091,17 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, #endif break; + case PR_GET_KEEPCAPS: + if (current->keep_capabilities) + error = 1; + break; + case PR_SET_KEEPCAPS: + if (arg2 != 0 && arg2 != 1) { + error = -EINVAL; + break; + } + current->keep_capabilities = arg2; + break; default: error = -EINVAL; break; |