diff options
Diffstat (limited to 'security/commoncap.c')
| -rw-r--r-- | security/commoncap.c | 59 |
1 files changed, 54 insertions, 5 deletions
diff --git a/security/commoncap.c b/security/commoncap.c index 778cb0cfc5d8..48ca5b092768 100644 --- a/security/commoncap.c +++ b/security/commoncap.c | |||
| @@ -24,6 +24,25 @@ | |||
| 24 | #include <linux/hugetlb.h> | 24 | #include <linux/hugetlb.h> |
| 25 | #include <linux/mount.h> | 25 | #include <linux/mount.h> |
| 26 | 26 | ||
| 27 | #ifdef CONFIG_SECURITY_FILE_CAPABILITIES | ||
| 28 | /* | ||
| 29 | * Because of the reduced scope of CAP_SETPCAP when filesystem | ||
| 30 | * capabilities are in effect, it is safe to allow this capability to | ||
| 31 | * be available in the default configuration. | ||
| 32 | */ | ||
| 33 | # define CAP_INIT_BSET CAP_FULL_SET | ||
| 34 | #else /* ie. ndef CONFIG_SECURITY_FILE_CAPABILITIES */ | ||
| 35 | # define CAP_INIT_BSET CAP_INIT_EFF_SET | ||
| 36 | #endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */ | ||
| 37 | |||
| 38 | kernel_cap_t cap_bset = CAP_INIT_BSET; /* systemwide capability bound */ | ||
| 39 | EXPORT_SYMBOL(cap_bset); | ||
| 40 | |||
| 41 | /* Global security state */ | ||
| 42 | |||
| 43 | unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */ | ||
| 44 | EXPORT_SYMBOL(securebits); | ||
| 45 | |||
| 27 | int cap_netlink_send(struct sock *sk, struct sk_buff *skb) | 46 | int cap_netlink_send(struct sock *sk, struct sk_buff *skb) |
| 28 | { | 47 | { |
| 29 | NETLINK_CB(skb).eff_cap = current->cap_effective; | 48 | NETLINK_CB(skb).eff_cap = current->cap_effective; |
| @@ -73,14 +92,44 @@ int cap_capget (struct task_struct *target, kernel_cap_t *effective, | |||
| 73 | return 0; | 92 | return 0; |
| 74 | } | 93 | } |
| 75 | 94 | ||
| 95 | #ifdef CONFIG_SECURITY_FILE_CAPABILITIES | ||
| 96 | |||
| 97 | static inline int cap_block_setpcap(struct task_struct *target) | ||
| 98 | { | ||
| 99 | /* | ||
| 100 | * No support for remote process capability manipulation with | ||
| 101 | * filesystem capability support. | ||
| 102 | */ | ||
| 103 | return (target != current); | ||
| 104 | } | ||
| 105 | |||
| 106 | static inline int cap_inh_is_capped(void) | ||
| 107 | { | ||
| 108 | /* | ||
| 109 | * return 1 if changes to the inheritable set are limited | ||
| 110 | * to the old permitted set. | ||
| 111 | */ | ||
| 112 | return !cap_capable(current, CAP_SETPCAP); | ||
| 113 | } | ||
| 114 | |||
| 115 | #else /* ie., ndef CONFIG_SECURITY_FILE_CAPABILITIES */ | ||
| 116 | |||
| 117 | static inline int cap_block_setpcap(struct task_struct *t) { return 0; } | ||
| 118 | static inline int cap_inh_is_capped(void) { return 1; } | ||
| 119 | |||
| 120 | #endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */ | ||
| 121 | |||
| 76 | int cap_capset_check (struct task_struct *target, kernel_cap_t *effective, | 122 | int cap_capset_check (struct task_struct *target, kernel_cap_t *effective, |
| 77 | kernel_cap_t *inheritable, kernel_cap_t *permitted) | 123 | kernel_cap_t *inheritable, kernel_cap_t *permitted) |
| 78 | { | 124 | { |
| 79 | /* Derived from kernel/capability.c:sys_capset. */ | 125 | if (cap_block_setpcap(target)) { |
| 80 | /* verify restrictions on target's new Inheritable set */ | 126 | return -EPERM; |
| 81 | if (!cap_issubset (*inheritable, | 127 | } |
| 82 | cap_combine (target->cap_inheritable, | 128 | if (cap_inh_is_capped() |
| 83 | current->cap_permitted))) { | 129 | && !cap_issubset(*inheritable, |
| 130 | cap_combine(target->cap_inheritable, | ||
| 131 | current->cap_permitted))) { | ||
| 132 | /* incapable of using this inheritable set */ | ||
| 84 | return -EPERM; | 133 | return -EPERM; |
| 85 | } | 134 | } |
| 86 | 135 | ||
