mirror of
https://github.com/torvalds/linux.git
synced 2024-12-01 08:31:37 +00:00
3898b1b4eb
Filesystem capability support makes it possible to do away with (set)uid-0 based privilege and use capabilities instead. That is, with filesystem support for capabilities but without this present patch, it is (conceptually) possible to manage a system with capabilities alone and never need to obtain privilege via (set)uid-0. Of course, conceptually isn't quite the same as currently possible since few user applications, certainly not enough to run a viable system, are currently prepared to leverage capabilities to exercise privilege. Further, many applications exist that may never get upgraded in this way, and the kernel will continue to want to support their setuid-0 base privilege needs. Where pure-capability applications evolve and replace setuid-0 binaries, it is desirable that there be a mechanisms by which they can contain their privilege. In addition to leveraging the per-process bounding and inheritable sets, this should include suppressing the privilege of the uid-0 superuser from the process' tree of children. The feature added by this patch can be leveraged to suppress the privilege associated with (set)uid-0. This suppression requires CAP_SETPCAP to initiate, and only immediately affects the 'current' process (it is inherited through fork()/exec()). This reimplementation differs significantly from the historical support for securebits which was system-wide, unwieldy and which has ultimately withered to a dead relic in the source of the modern kernel. With this patch applied a process, that is capable(CAP_SETPCAP), can now drop all legacy privilege (through uid=0) for itself and all subsequently fork()'d/exec()'d children with: prctl(PR_SET_SECUREBITS, 0x2f); This patch represents a no-op unless CONFIG_SECURITY_FILE_CAPABILITIES is enabled at configure time. [akpm@linux-foundation.org: fix uninitialised var warning] [serue@us.ibm.com: capabilities: use cap_task_prctl when !CONFIG_SECURITY] Signed-off-by: Andrew G. Morgan <morgan@kernel.org> Acked-by: Serge Hallyn <serue@us.ibm.com> Reviewed-by: James Morris <jmorris@namei.org> Cc: Stephen Smalley <sds@tycho.nsa.gov> Cc: Paul Moore <paul.moore@hp.com> Signed-off-by: Serge E. Hallyn <serue@us.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
83 lines
2.3 KiB
C
83 lines
2.3 KiB
C
/*
|
|
* Capabilities Linux Security Module
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
*/
|
|
|
|
#include <linux/init.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/security.h>
|
|
#include <linux/file.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/mman.h>
|
|
#include <linux/pagemap.h>
|
|
#include <linux/swap.h>
|
|
#include <linux/skbuff.h>
|
|
#include <linux/netlink.h>
|
|
#include <linux/ptrace.h>
|
|
#include <linux/moduleparam.h>
|
|
|
|
static struct security_operations capability_ops = {
|
|
.ptrace = cap_ptrace,
|
|
.capget = cap_capget,
|
|
.capset_check = cap_capset_check,
|
|
.capset_set = cap_capset_set,
|
|
.capable = cap_capable,
|
|
.settime = cap_settime,
|
|
.netlink_send = cap_netlink_send,
|
|
.netlink_recv = cap_netlink_recv,
|
|
|
|
.bprm_apply_creds = cap_bprm_apply_creds,
|
|
.bprm_set_security = cap_bprm_set_security,
|
|
.bprm_secureexec = cap_bprm_secureexec,
|
|
|
|
.inode_setxattr = cap_inode_setxattr,
|
|
.inode_removexattr = cap_inode_removexattr,
|
|
.inode_need_killpriv = cap_inode_need_killpriv,
|
|
.inode_killpriv = cap_inode_killpriv,
|
|
|
|
.task_setscheduler = cap_task_setscheduler,
|
|
.task_setioprio = cap_task_setioprio,
|
|
.task_setnice = cap_task_setnice,
|
|
.task_post_setuid = cap_task_post_setuid,
|
|
.task_prctl = cap_task_prctl,
|
|
.task_reparent_to_init = cap_task_reparent_to_init,
|
|
|
|
.syslog = cap_syslog,
|
|
|
|
.vm_enough_memory = cap_vm_enough_memory,
|
|
};
|
|
|
|
/* flag to keep track of how we were registered */
|
|
static int secondary;
|
|
|
|
static int capability_disable;
|
|
module_param_named(disable, capability_disable, int, 0);
|
|
|
|
static int __init capability_init (void)
|
|
{
|
|
if (capability_disable) {
|
|
printk(KERN_INFO "Capabilities disabled at initialization\n");
|
|
return 0;
|
|
}
|
|
/* register ourselves with the security framework */
|
|
if (register_security (&capability_ops)) {
|
|
/* try registering with primary module */
|
|
if (mod_reg_security (KBUILD_MODNAME, &capability_ops)) {
|
|
printk (KERN_INFO "Failure registering capabilities "
|
|
"with primary security module.\n");
|
|
return -EINVAL;
|
|
}
|
|
secondary = 1;
|
|
}
|
|
printk (KERN_INFO "Capability LSM initialized%s\n",
|
|
secondary ? " as secondary" : "");
|
|
return 0;
|
|
}
|
|
|
|
security_initcall (capability_init);
|