aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
authorCasey Schaufler <casey@schaufler-ca.com>2015-05-02 18:11:42 -0400
committerJames Morris <james.l.morris@oracle.com>2015-05-12 01:00:41 -0400
commitb1d9e6b0646d0e5ee5d9050bd236b6c65d66faef (patch)
treebefe73902cf0797dabb704cf6688b3fe335fc19e /security/selinux/hooks.c
parente20b043a6902ecb61c2c84355c3bae5149f391db (diff)
LSM: Switch to lists of hooks
Instead of using a vector of security operations with explicit, special case stacking of the capability and yama hooks use lists of hooks with capability and yama hooks included as appropriate. The security_operations structure is no longer required. Instead, there is a union of the function pointers that allows all the hooks lists to use a common mechanism for list management while retaining typing. Each module supplies an array describing the hooks it provides instead of a sparsely populated security_operations structure. The description includes the element that gets put on the hook list, avoiding the issues surrounding individual element allocation. The method for registering security modules is changed to reflect the information available. The method for removing a module, currently only used by SELinux, has also changed. It should be generic now, however if there are potential race conditions based on ordering of hook removal that needs to be addressed by the calling module. The security hooks are called from the lists and the first failure is returned. Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> Acked-by: John Johansen <john.johansen@canonical.com> Acked-by: Kees Cook <keescook@chromium.org> Acked-by: Paul Moore <paul@paul-moore.com> Acked-by: Stephen Smalley <sds@tycho.nsa.gov> Acked-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: James Morris <james.l.morris@oracle.com>
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c94
1 files changed, 15 insertions, 79 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 0cf105f346d4..06c9dd962c3c 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1990,12 +1990,6 @@ static int selinux_binder_transfer_file(struct task_struct *from,
1990static int selinux_ptrace_access_check(struct task_struct *child, 1990static int selinux_ptrace_access_check(struct task_struct *child,
1991 unsigned int mode) 1991 unsigned int mode)
1992{ 1992{
1993 int rc;
1994
1995 rc = cap_ptrace_access_check(child, mode);
1996 if (rc)
1997 return rc;
1998
1999 if (mode & PTRACE_MODE_READ) { 1993 if (mode & PTRACE_MODE_READ) {
2000 u32 sid = current_sid(); 1994 u32 sid = current_sid();
2001 u32 csid = task_sid(child); 1995 u32 csid = task_sid(child);
@@ -2007,25 +2001,13 @@ static int selinux_ptrace_access_check(struct task_struct *child,
2007 2001
2008static int selinux_ptrace_traceme(struct task_struct *parent) 2002static int selinux_ptrace_traceme(struct task_struct *parent)
2009{ 2003{
2010 int rc;
2011
2012 rc = cap_ptrace_traceme(parent);
2013 if (rc)
2014 return rc;
2015
2016 return task_has_perm(parent, current, PROCESS__PTRACE); 2004 return task_has_perm(parent, current, PROCESS__PTRACE);
2017} 2005}
2018 2006
2019static int selinux_capget(struct task_struct *target, kernel_cap_t *effective, 2007static int selinux_capget(struct task_struct *target, kernel_cap_t *effective,
2020 kernel_cap_t *inheritable, kernel_cap_t *permitted) 2008 kernel_cap_t *inheritable, kernel_cap_t *permitted)
2021{ 2009{
2022 int error; 2010 return current_has_perm(target, PROCESS__GETCAP);
2023
2024 error = current_has_perm(target, PROCESS__GETCAP);
2025 if (error)
2026 return error;
2027
2028 return cap_capget(target, effective, inheritable, permitted);
2029} 2011}
2030 2012
2031static int selinux_capset(struct cred *new, const struct cred *old, 2013static int selinux_capset(struct cred *new, const struct cred *old,
@@ -2033,13 +2015,6 @@ static int selinux_capset(struct cred *new, const struct cred *old,
2033 const kernel_cap_t *inheritable, 2015 const kernel_cap_t *inheritable,
2034 const kernel_cap_t *permitted) 2016 const kernel_cap_t *permitted)
2035{ 2017{
2036 int error;
2037
2038 error = cap_capset(new, old,
2039 effective, inheritable, permitted);
2040 if (error)
2041 return error;
2042
2043 return cred_has_perm(old, new, PROCESS__SETCAP); 2018 return cred_has_perm(old, new, PROCESS__SETCAP);
2044} 2019}
2045 2020
@@ -2056,12 +2031,6 @@ static int selinux_capset(struct cred *new, const struct cred *old,
2056static int selinux_capable(const struct cred *cred, struct user_namespace *ns, 2031static int selinux_capable(const struct cred *cred, struct user_namespace *ns,
2057 int cap, int audit) 2032 int cap, int audit)
2058{ 2033{
2059 int rc;
2060
2061 rc = cap_capable(cred, ns, cap, audit);
2062 if (rc)
2063 return rc;
2064
2065 return cred_has_capability(cred, cap, audit); 2034 return cred_has_capability(cred, cap, audit);
2066} 2035}
2067 2036
@@ -2139,12 +2108,12 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)
2139{ 2108{
2140 int rc, cap_sys_admin = 0; 2109 int rc, cap_sys_admin = 0;
2141 2110
2142 rc = selinux_capable(current_cred(), &init_user_ns, CAP_SYS_ADMIN, 2111 rc = cred_has_capability(current_cred(), CAP_SYS_ADMIN,
2143 SECURITY_CAP_NOAUDIT); 2112 SECURITY_CAP_NOAUDIT);
2144 if (rc == 0) 2113 if (rc == 0)
2145 cap_sys_admin = 1; 2114 cap_sys_admin = 1;
2146 2115
2147 return __vm_enough_memory(mm, pages, cap_sys_admin); 2116 return cap_sys_admin;
2148} 2117}
2149 2118
2150/* binprm security operations */ 2119/* binprm security operations */
@@ -2193,10 +2162,6 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
2193 struct inode *inode = file_inode(bprm->file); 2162 struct inode *inode = file_inode(bprm->file);
2194 int rc; 2163 int rc;
2195 2164
2196 rc = cap_bprm_set_creds(bprm);
2197 if (rc)
2198 return rc;
2199
2200 /* SELinux context only depends on initial program or script and not 2165 /* SELinux context only depends on initial program or script and not
2201 * the script interpreter */ 2166 * the script interpreter */
2202 if (bprm->cred_prepared) 2167 if (bprm->cred_prepared)
@@ -2320,7 +2285,7 @@ static int selinux_bprm_secureexec(struct linux_binprm *bprm)
2320 PROCESS__NOATSECURE, NULL); 2285 PROCESS__NOATSECURE, NULL);
2321 } 2286 }
2322 2287
2323 return (atsecure || cap_bprm_secureexec(bprm)); 2288 return !!atsecure;
2324} 2289}
2325 2290
2326static int match_file(const void *p, struct file *file, unsigned fd) 2291static int match_file(const void *p, struct file *file, unsigned fd)
@@ -3132,8 +3097,11 @@ static int selinux_inode_getsecurity(const struct inode *inode, const char *name
3132 * and lack of permission just means that we fall back to the 3097 * and lack of permission just means that we fall back to the
3133 * in-core context value, not a denial. 3098 * in-core context value, not a denial.
3134 */ 3099 */
3135 error = selinux_capable(current_cred(), &init_user_ns, CAP_MAC_ADMIN, 3100 error = cap_capable(current_cred(), &init_user_ns, CAP_MAC_ADMIN,
3136 SECURITY_CAP_NOAUDIT); 3101 SECURITY_CAP_NOAUDIT);
3102 if (!error)
3103 error = cred_has_capability(current_cred(), CAP_MAC_ADMIN,
3104 SECURITY_CAP_NOAUDIT);
3137 if (!error) 3105 if (!error)
3138 error = security_sid_to_context_force(isec->sid, &context, 3106 error = security_sid_to_context_force(isec->sid, &context,
3139 &size); 3107 &size);
@@ -3318,12 +3286,7 @@ error:
3318 3286
3319static int selinux_mmap_addr(unsigned long addr) 3287static int selinux_mmap_addr(unsigned long addr)
3320{ 3288{
3321 int rc; 3289 int rc = 0;
3322
3323 /* do DAC check on address space usage */
3324 rc = cap_mmap_addr(addr);
3325 if (rc)
3326 return rc;
3327 3290
3328 if (addr < CONFIG_LSM_MMAP_MIN_ADDR) { 3291 if (addr < CONFIG_LSM_MMAP_MIN_ADDR) {
3329 u32 sid = current_sid(); 3292 u32 sid = current_sid();
@@ -3639,23 +3602,11 @@ static void selinux_task_getsecid(struct task_struct *p, u32 *secid)
3639 3602
3640static int selinux_task_setnice(struct task_struct *p, int nice) 3603static int selinux_task_setnice(struct task_struct *p, int nice)
3641{ 3604{
3642 int rc;
3643
3644 rc = cap_task_setnice(p, nice);
3645 if (rc)
3646 return rc;
3647
3648 return current_has_perm(p, PROCESS__SETSCHED); 3605 return current_has_perm(p, PROCESS__SETSCHED);
3649} 3606}
3650 3607
3651static int selinux_task_setioprio(struct task_struct *p, int ioprio) 3608static int selinux_task_setioprio(struct task_struct *p, int ioprio)
3652{ 3609{
3653 int rc;
3654
3655 rc = cap_task_setioprio(p, ioprio);
3656 if (rc)
3657 return rc;
3658
3659 return current_has_perm(p, PROCESS__SETSCHED); 3610 return current_has_perm(p, PROCESS__SETSCHED);
3660} 3611}
3661 3612
@@ -3681,12 +3632,6 @@ static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource,
3681 3632
3682static int selinux_task_setscheduler(struct task_struct *p) 3633static int selinux_task_setscheduler(struct task_struct *p)
3683{ 3634{
3684 int rc;
3685
3686 rc = cap_task_setscheduler(p);
3687 if (rc)
3688 return rc;
3689
3690 return current_has_perm(p, PROCESS__SETSCHED); 3635 return current_has_perm(p, PROCESS__SETSCHED);
3691} 3636}
3692 3637
@@ -5097,12 +5042,6 @@ static unsigned int selinux_ipv6_postroute(const struct nf_hook_ops *ops,
5097 5042
5098static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) 5043static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
5099{ 5044{
5100 int err;
5101
5102 err = cap_netlink_send(sk, skb);
5103 if (err)
5104 return err;
5105
5106 return selinux_nlmsg_perm(sk, skb); 5045 return selinux_nlmsg_perm(sk, skb);
5107} 5046}
5108 5047
@@ -5840,9 +5779,7 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer)
5840 5779
5841#endif 5780#endif
5842 5781
5843static struct security_operations selinux_ops = { 5782static struct security_hook_list selinux_hooks[] = {
5844 LSM_HOOK_INIT(name, "selinux"),
5845
5846 LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr), 5783 LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr),
5847 LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction), 5784 LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction),
5848 LSM_HOOK_INIT(binder_transfer_binder, selinux_binder_transfer_binder), 5785 LSM_HOOK_INIT(binder_transfer_binder, selinux_binder_transfer_binder),
@@ -6055,7 +5992,7 @@ static struct security_operations selinux_ops = {
6055 5992
6056static __init int selinux_init(void) 5993static __init int selinux_init(void)
6057{ 5994{
6058 if (!security_module_enable(&selinux_ops)) { 5995 if (!security_module_enable("selinux")) {
6059 selinux_enabled = 0; 5996 selinux_enabled = 0;
6060 return 0; 5997 return 0;
6061 } 5998 }
@@ -6077,8 +6014,7 @@ static __init int selinux_init(void)
6077 0, SLAB_PANIC, NULL); 6014 0, SLAB_PANIC, NULL);
6078 avc_init(); 6015 avc_init();
6079 6016
6080 if (register_security(&selinux_ops)) 6017 security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks));
6081 panic("SELinux: Unable to register with kernel.\n");
6082 6018
6083 if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET)) 6019 if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))
6084 panic("SELinux: Unable to register AVC netcache callback\n"); 6020 panic("SELinux: Unable to register AVC netcache callback\n");
@@ -6206,7 +6142,7 @@ int selinux_disable(void)
6206 selinux_disabled = 1; 6142 selinux_disabled = 1;
6207 selinux_enabled = 0; 6143 selinux_enabled = 0;
6208 6144
6209 reset_security_ops(); 6145 security_delete_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks));
6210 6146
6211 /* Try to destroy the avc node cache */ 6147 /* Try to destroy the avc node cache */
6212 avc_disable(); 6148 avc_disable();