aboutsummaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
authorStephen Smalley <sds@tycho.nsa.gov>2012-11-05 08:15:34 -0500
committerRuchi Kandoi <kandoiruchi@google.com>2015-02-03 16:49:43 -0800
commit1058a5ce897324d57052c132127bf4b0ee2419ce (patch)
tree4964a7ec5f16d2509d99446693221b21cdc0d2e5 /security
parent0153a506236fd16ff836e8117ead155dc981ad32 (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 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). This support is used by SE Android, http://selinuxproject.org/page/SEAndroid. Change-Id: I9a64a87825df2e60b9c51400377af4a9cd1c4049 Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
Diffstat (limited to 'security')
-rw-r--r--security/capability.c24
-rw-r--r--security/security.c20
-rw-r--r--security/selinux/hooks.c66
-rw-r--r--security/selinux/include/classmap.h1
4 files changed, 111 insertions, 0 deletions
diff --git a/security/capability.c b/security/capability.c
index d68c57a62bcf..ef951b004140 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -12,6 +12,26 @@
#include <linux/security.h>
+static int cap_binder_set_context_mgr(struct task_struct *mgr)
+{
+ return 0;
+}
+
+static int cap_binder_transaction(struct task_struct *from, struct task_struct *to)
+{
+ return 0;
+}
+
+static int cap_binder_transfer_binder(struct task_struct *from, struct task_struct *to)
+{
+ return 0;
+}
+
+static int cap_binder_transfer_file(struct task_struct *from, struct task_struct *to, struct file *file)
+{
+ return 0;
+}
+
static int cap_syslog(int type)
{
return 0;
@@ -930,6 +950,10 @@ static void cap_audit_rule_free(void *lsmrule)
void __init security_fixup_ops(struct security_operations *ops)
{
+ set_to_cap_if_null(ops, binder_set_context_mgr);
+ set_to_cap_if_null(ops, binder_transaction);
+ set_to_cap_if_null(ops, binder_transfer_binder);
+ set_to_cap_if_null(ops, binder_transfer_file);
set_to_cap_if_null(ops, ptrace_access_check);
set_to_cap_if_null(ops, ptrace_traceme);
set_to_cap_if_null(ops, capget);
diff --git a/security/security.c b/security/security.c
index 18b35c63fc0c..6ad484c79309 100644
--- a/security/security.c
+++ b/security/security.c
@@ -135,6 +135,26 @@ int __init register_security(struct security_operations *ops)
/* Security operations */
+int security_binder_set_context_mgr(struct task_struct *mgr)
+{
+ return security_ops->binder_set_context_mgr(mgr);
+}
+
+int security_binder_transaction(struct task_struct *from, struct task_struct *to)
+{
+ return security_ops->binder_transaction(from, to);
+}
+
+int security_binder_transfer_binder(struct task_struct *from, struct task_struct *to)
+{
+ return security_ops->binder_transfer_binder(from, to);
+}
+
+int security_binder_transfer_file(struct task_struct *from, struct task_struct *to, struct file *file)
+{
+ return security_ops->binder_transfer_file(from, to, file);
+}
+
int security_ptrace_access_check(struct task_struct *child, unsigned int mode)
{
#ifdef CONFIG_SECURITY_YAMA_STACKED
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index c603b20356ad..800eeeb15606 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1935,6 +1935,67 @@ static inline u32 open_file_to_av(struct file *file)
/* Hook functions begin here. */
+static int selinux_binder_set_context_mgr(struct task_struct *mgr)
+{
+ u32 mysid = current_sid();
+ u32 mgrsid = task_sid(mgr);
+
+ return avc_has_perm(mysid, mgrsid, SECCLASS_BINDER, BINDER__SET_CONTEXT_MGR, NULL);
+}
+
+static int selinux_binder_transaction(struct task_struct *from, struct task_struct *to)
+{
+ u32 mysid = current_sid();
+ u32 fromsid = task_sid(from);
+ u32 tosid = task_sid(to);
+ int rc;
+
+ if (mysid != fromsid) {
+ rc = avc_has_perm(mysid, fromsid, SECCLASS_BINDER, BINDER__IMPERSONATE, NULL);
+ if (rc)
+ return rc;
+ }
+
+ return avc_has_perm(fromsid, tosid, SECCLASS_BINDER, BINDER__CALL, NULL);
+}
+
+static int selinux_binder_transfer_binder(struct task_struct *from, struct task_struct *to)
+{
+ u32 fromsid = task_sid(from);
+ u32 tosid = task_sid(to);
+ return avc_has_perm(fromsid, tosid, SECCLASS_BINDER, BINDER__TRANSFER, NULL);
+}
+
+static int selinux_binder_transfer_file(struct task_struct *from, struct task_struct *to, struct file *file)
+{
+ u32 sid = task_sid(to);
+ struct file_security_struct *fsec = file->f_security;
+ struct inode *inode = file->f_path.dentry->d_inode;
+ struct inode_security_struct *isec = inode->i_security;
+ struct common_audit_data ad;
+ struct selinux_audit_data sad = {0,};
+ int rc;
+
+ COMMON_AUDIT_DATA_INIT(&ad, PATH);
+ ad.u.path = file->f_path;
+ ad.selinux_audit_data = &sad;
+
+ if (sid != fsec->sid) {
+ rc = avc_has_perm(sid, fsec->sid,
+ SECCLASS_FD,
+ FD__USE,
+ &ad);
+ if (rc)
+ return rc;
+ }
+
+ if (unlikely(IS_PRIVATE(inode)))
+ return 0;
+
+ return avc_has_perm(sid, isec->sid, isec->sclass, file_to_av(file),
+ &ad);
+}
+
static int selinux_ptrace_access_check(struct task_struct *child,
unsigned int mode)
{
@@ -5812,6 +5873,11 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer)
static struct security_operations selinux_ops = {
.name = "selinux",
+ .binder_set_context_mgr = selinux_binder_set_context_mgr,
+ .binder_transaction = selinux_binder_transaction,
+ .binder_transfer_binder = selinux_binder_transfer_binder,
+ .binder_transfer_file = selinux_binder_transfer_file,
+
.ptrace_access_check = selinux_ptrace_access_check,
.ptrace_traceme = selinux_ptrace_traceme,
.capget = selinux_capget,
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index be491a74c1ed..bdc9325a4659 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -151,5 +151,6 @@ struct security_class_mapping secclass_map[] = {
{ "kernel_service", { "use_as_override", "create_files_as", NULL } },
{ "tun_socket",
{ COMMON_SOCK_PERMS, "attach_queue", NULL } },
+ { "binder", { "impersonate", "call", "set_context_mgr", "transfer", NULL } },
{ NULL }
};