aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorStephen Smalley <sds@tycho.nsa.gov>2015-01-21 10:54:10 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-01-25 12:17:57 -0500
commit79af73079d753b2d04e46f7445716d3b5f914dbd (patch)
tree565ce3d58ccae8765fe13e20064b3ba48eaa0ebc /security
parent79563db9ddd37908343103debf20da716ccc5ce4 (diff)
Add security hooks to binder and implement the hooks for SELinux.
Add security hooks to the binder and implement the hooks for SELinux. The security hooks enable security modules such as SELinux to implement controls over binder IPC. The security hooks include support for controlling what process can become the binder context manager (binder_set_context_mgr), controlling the ability of a process to invoke a binder transaction/IPC to another process (binder_transaction), controlling the ability of a process to transfer a binder reference to another process (binder_transfer_binder), and controlling the ability of a process to transfer an open file to another process (binder_transfer_file). These hooks have been included in the Android kernel trees since Android 4.3. (Updated to reflect upstream relocation and changes to the binder driver, changes to the LSM audit data structures, coding style cleanups, and to add inline documentation for the hooks). Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> Acked-by: Nick Kralevich <nnk@google.com> Acked-by: Jeffrey Vander Stoep <jeffv@google.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'security')
-rw-r--r--security/capability.c27
-rw-r--r--security/security.c23
-rw-r--r--security/selinux/hooks.c73
-rw-r--r--security/selinux/include/classmap.h2
4 files changed, 125 insertions, 0 deletions
diff --git a/security/capability.c b/security/capability.c
index d68c57a62bcf..070dd46f62f4 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -12,6 +12,29 @@
12 12
13#include <linux/security.h> 13#include <linux/security.h>
14 14
15static int cap_binder_set_context_mgr(struct task_struct *mgr)
16{
17 return 0;
18}
19
20static int cap_binder_transaction(struct task_struct *from,
21 struct task_struct *to)
22{
23 return 0;
24}
25
26static int cap_binder_transfer_binder(struct task_struct *from,
27 struct task_struct *to)
28{
29 return 0;
30}
31
32static int cap_binder_transfer_file(struct task_struct *from,
33 struct task_struct *to, struct file *file)
34{
35 return 0;
36}
37
15static int cap_syslog(int type) 38static int cap_syslog(int type)
16{ 39{
17 return 0; 40 return 0;
@@ -930,6 +953,10 @@ static void cap_audit_rule_free(void *lsmrule)
930 953
931void __init security_fixup_ops(struct security_operations *ops) 954void __init security_fixup_ops(struct security_operations *ops)
932{ 955{
956 set_to_cap_if_null(ops, binder_set_context_mgr);
957 set_to_cap_if_null(ops, binder_transaction);
958 set_to_cap_if_null(ops, binder_transfer_binder);
959 set_to_cap_if_null(ops, binder_transfer_file);
933 set_to_cap_if_null(ops, ptrace_access_check); 960 set_to_cap_if_null(ops, ptrace_access_check);
934 set_to_cap_if_null(ops, ptrace_traceme); 961 set_to_cap_if_null(ops, ptrace_traceme);
935 set_to_cap_if_null(ops, capget); 962 set_to_cap_if_null(ops, capget);
diff --git a/security/security.c b/security/security.c
index 18b35c63fc0c..b196de34b19f 100644
--- a/security/security.c
+++ b/security/security.c
@@ -135,6 +135,29 @@ int __init register_security(struct security_operations *ops)
135 135
136/* Security operations */ 136/* Security operations */
137 137
138int security_binder_set_context_mgr(struct task_struct *mgr)
139{
140 return security_ops->binder_set_context_mgr(mgr);
141}
142
143int security_binder_transaction(struct task_struct *from,
144 struct task_struct *to)
145{
146 return security_ops->binder_transaction(from, to);
147}
148
149int security_binder_transfer_binder(struct task_struct *from,
150 struct task_struct *to)
151{
152 return security_ops->binder_transfer_binder(from, to);
153}
154
155int security_binder_transfer_file(struct task_struct *from,
156 struct task_struct *to, struct file *file)
157{
158 return security_ops->binder_transfer_file(from, to, file);
159}
160
138int security_ptrace_access_check(struct task_struct *child, unsigned int mode) 161int security_ptrace_access_check(struct task_struct *child, unsigned int mode)
139{ 162{
140#ifdef CONFIG_SECURITY_YAMA_STACKED 163#ifdef CONFIG_SECURITY_YAMA_STACKED
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 6da7532893a1..9d984bfb978b 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1933,6 +1933,74 @@ static inline u32 open_file_to_av(struct file *file)
1933 1933
1934/* Hook functions begin here. */ 1934/* Hook functions begin here. */
1935 1935
1936static int selinux_binder_set_context_mgr(struct task_struct *mgr)
1937{
1938 u32 mysid = current_sid();
1939 u32 mgrsid = task_sid(mgr);
1940
1941 return avc_has_perm(mysid, mgrsid, SECCLASS_BINDER,
1942 BINDER__SET_CONTEXT_MGR, NULL);
1943}
1944
1945static int selinux_binder_transaction(struct task_struct *from,
1946 struct task_struct *to)
1947{
1948 u32 mysid = current_sid();
1949 u32 fromsid = task_sid(from);
1950 u32 tosid = task_sid(to);
1951 int rc;
1952
1953 if (mysid != fromsid) {
1954 rc = avc_has_perm(mysid, fromsid, SECCLASS_BINDER,
1955 BINDER__IMPERSONATE, NULL);
1956 if (rc)
1957 return rc;
1958 }
1959
1960 return avc_has_perm(fromsid, tosid, SECCLASS_BINDER, BINDER__CALL,
1961 NULL);
1962}
1963
1964static int selinux_binder_transfer_binder(struct task_struct *from,
1965 struct task_struct *to)
1966{
1967 u32 fromsid = task_sid(from);
1968 u32 tosid = task_sid(to);
1969
1970 return avc_has_perm(fromsid, tosid, SECCLASS_BINDER, BINDER__TRANSFER,
1971 NULL);
1972}
1973
1974static int selinux_binder_transfer_file(struct task_struct *from,
1975 struct task_struct *to,
1976 struct file *file)
1977{
1978 u32 sid = task_sid(to);
1979 struct file_security_struct *fsec = file->f_security;
1980 struct inode *inode = file->f_path.dentry->d_inode;
1981 struct inode_security_struct *isec = inode->i_security;
1982 struct common_audit_data ad;
1983 int rc;
1984
1985 ad.type = LSM_AUDIT_DATA_PATH;
1986 ad.u.path = file->f_path;
1987
1988 if (sid != fsec->sid) {
1989 rc = avc_has_perm(sid, fsec->sid,
1990 SECCLASS_FD,
1991 FD__USE,
1992 &ad);
1993 if (rc)
1994 return rc;
1995 }
1996
1997 if (unlikely(IS_PRIVATE(inode)))
1998 return 0;
1999
2000 return avc_has_perm(sid, isec->sid, isec->sclass, file_to_av(file),
2001 &ad);
2002}
2003
1936static int selinux_ptrace_access_check(struct task_struct *child, 2004static int selinux_ptrace_access_check(struct task_struct *child,
1937 unsigned int mode) 2005 unsigned int mode)
1938{ 2006{
@@ -5810,6 +5878,11 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer)
5810static struct security_operations selinux_ops = { 5878static struct security_operations selinux_ops = {
5811 .name = "selinux", 5879 .name = "selinux",
5812 5880
5881 .binder_set_context_mgr = selinux_binder_set_context_mgr,
5882 .binder_transaction = selinux_binder_transaction,
5883 .binder_transfer_binder = selinux_binder_transfer_binder,
5884 .binder_transfer_file = selinux_binder_transfer_file,
5885
5813 .ptrace_access_check = selinux_ptrace_access_check, 5886 .ptrace_access_check = selinux_ptrace_access_check,
5814 .ptrace_traceme = selinux_ptrace_traceme, 5887 .ptrace_traceme = selinux_ptrace_traceme,
5815 .capget = selinux_capget, 5888 .capget = selinux_capget,
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index be491a74c1ed..eccd61b3de8a 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -151,5 +151,7 @@ struct security_class_mapping secclass_map[] = {
151 { "kernel_service", { "use_as_override", "create_files_as", NULL } }, 151 { "kernel_service", { "use_as_override", "create_files_as", NULL } },
152 { "tun_socket", 152 { "tun_socket",
153 { COMMON_SOCK_PERMS, "attach_queue", NULL } }, 153 { COMMON_SOCK_PERMS, "attach_queue", NULL } },
154 { "binder", { "impersonate", "call", "set_context_mgr", "transfer",
155 NULL } },
154 { NULL } 156 { NULL }
155 }; 157 };