aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/android/binder.c26
-rw-r--r--include/linux/security.h58
-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
6 files changed, 209 insertions, 0 deletions
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 8c43521d3f11..33b09b6568a4 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -37,6 +37,7 @@
37#include <linux/vmalloc.h> 37#include <linux/vmalloc.h>
38#include <linux/slab.h> 38#include <linux/slab.h>
39#include <linux/pid_namespace.h> 39#include <linux/pid_namespace.h>
40#include <linux/security.h>
40 41
41#ifdef CONFIG_ANDROID_BINDER_IPC_32BIT 42#ifdef CONFIG_ANDROID_BINDER_IPC_32BIT
42#define BINDER_IPC_32BIT 1 43#define BINDER_IPC_32BIT 1
@@ -1400,6 +1401,11 @@ static void binder_transaction(struct binder_proc *proc,
1400 return_error = BR_DEAD_REPLY; 1401 return_error = BR_DEAD_REPLY;
1401 goto err_dead_binder; 1402 goto err_dead_binder;
1402 } 1403 }
1404 if (security_binder_transaction(proc->tsk,
1405 target_proc->tsk) < 0) {
1406 return_error = BR_FAILED_REPLY;
1407 goto err_invalid_target_handle;
1408 }
1403 if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack) { 1409 if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack) {
1404 struct binder_transaction *tmp; 1410 struct binder_transaction *tmp;
1405 1411
@@ -1551,6 +1557,11 @@ static void binder_transaction(struct binder_proc *proc,
1551 return_error = BR_FAILED_REPLY; 1557 return_error = BR_FAILED_REPLY;
1552 goto err_binder_get_ref_for_node_failed; 1558 goto err_binder_get_ref_for_node_failed;
1553 } 1559 }
1560 if (security_binder_transfer_binder(proc->tsk,
1561 target_proc->tsk)) {
1562 return_error = BR_FAILED_REPLY;
1563 goto err_binder_get_ref_for_node_failed;
1564 }
1554 ref = binder_get_ref_for_node(target_proc, node); 1565 ref = binder_get_ref_for_node(target_proc, node);
1555 if (ref == NULL) { 1566 if (ref == NULL) {
1556 return_error = BR_FAILED_REPLY; 1567 return_error = BR_FAILED_REPLY;
@@ -1581,6 +1592,11 @@ static void binder_transaction(struct binder_proc *proc,
1581 return_error = BR_FAILED_REPLY; 1592 return_error = BR_FAILED_REPLY;
1582 goto err_binder_get_ref_failed; 1593 goto err_binder_get_ref_failed;
1583 } 1594 }
1595 if (security_binder_transfer_binder(proc->tsk,
1596 target_proc->tsk)) {
1597 return_error = BR_FAILED_REPLY;
1598 goto err_binder_get_ref_failed;
1599 }
1584 if (ref->node->proc == target_proc) { 1600 if (ref->node->proc == target_proc) {
1585 if (fp->type == BINDER_TYPE_HANDLE) 1601 if (fp->type == BINDER_TYPE_HANDLE)
1586 fp->type = BINDER_TYPE_BINDER; 1602 fp->type = BINDER_TYPE_BINDER;
@@ -1638,6 +1654,13 @@ static void binder_transaction(struct binder_proc *proc,
1638 return_error = BR_FAILED_REPLY; 1654 return_error = BR_FAILED_REPLY;
1639 goto err_fget_failed; 1655 goto err_fget_failed;
1640 } 1656 }
1657 if (security_binder_transfer_file(proc->tsk,
1658 target_proc->tsk,
1659 file) < 0) {
1660 fput(file);
1661 return_error = BR_FAILED_REPLY;
1662 goto err_get_unused_fd_failed;
1663 }
1641 target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC); 1664 target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC);
1642 if (target_fd < 0) { 1665 if (target_fd < 0) {
1643 fput(file); 1666 fput(file);
@@ -2675,6 +2698,9 @@ static int binder_ioctl_set_ctx_mgr(struct file *filp)
2675 ret = -EBUSY; 2698 ret = -EBUSY;
2676 goto out; 2699 goto out;
2677 } 2700 }
2701 ret = security_binder_set_context_mgr(proc->tsk);
2702 if (ret < 0)
2703 goto out;
2678 if (uid_valid(binder_context_mgr_uid)) { 2704 if (uid_valid(binder_context_mgr_uid)) {
2679 if (!uid_eq(binder_context_mgr_uid, curr_euid)) { 2705 if (!uid_eq(binder_context_mgr_uid, curr_euid)) {
2680 pr_err("BINDER_SET_CONTEXT_MGR bad uid %d != %d\n", 2706 pr_err("BINDER_SET_CONTEXT_MGR bad uid %d != %d\n",
diff --git a/include/linux/security.h b/include/linux/security.h
index ba96471c11ba..a1b7dbd127ff 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1281,6 +1281,25 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
1281 * @alter contains the flag indicating whether changes are to be made. 1281 * @alter contains the flag indicating whether changes are to be made.
1282 * Return 0 if permission is granted. 1282 * Return 0 if permission is granted.
1283 * 1283 *
1284 * @binder_set_context_mgr
1285 * Check whether @mgr is allowed to be the binder context manager.
1286 * @mgr contains the task_struct for the task being registered.
1287 * Return 0 if permission is granted.
1288 * @binder_transaction
1289 * Check whether @from is allowed to invoke a binder transaction call
1290 * to @to.
1291 * @from contains the task_struct for the sending task.
1292 * @to contains the task_struct for the receiving task.
1293 * @binder_transfer_binder
1294 * Check whether @from is allowed to transfer a binder reference to @to.
1295 * @from contains the task_struct for the sending task.
1296 * @to contains the task_struct for the receiving task.
1297 * @binder_transfer_file
1298 * Check whether @from is allowed to transfer @file to @to.
1299 * @from contains the task_struct for the sending task.
1300 * @file contains the struct file being transferred.
1301 * @to contains the task_struct for the receiving task.
1302 *
1284 * @ptrace_access_check: 1303 * @ptrace_access_check:
1285 * Check permission before allowing the current process to trace the 1304 * Check permission before allowing the current process to trace the
1286 * @child process. 1305 * @child process.
@@ -1441,6 +1460,14 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
1441struct security_operations { 1460struct security_operations {
1442 char name[SECURITY_NAME_MAX + 1]; 1461 char name[SECURITY_NAME_MAX + 1];
1443 1462
1463 int (*binder_set_context_mgr) (struct task_struct *mgr);
1464 int (*binder_transaction) (struct task_struct *from,
1465 struct task_struct *to);
1466 int (*binder_transfer_binder) (struct task_struct *from,
1467 struct task_struct *to);
1468 int (*binder_transfer_file) (struct task_struct *from,
1469 struct task_struct *to, struct file *file);
1470
1444 int (*ptrace_access_check) (struct task_struct *child, unsigned int mode); 1471 int (*ptrace_access_check) (struct task_struct *child, unsigned int mode);
1445 int (*ptrace_traceme) (struct task_struct *parent); 1472 int (*ptrace_traceme) (struct task_struct *parent);
1446 int (*capget) (struct task_struct *target, 1473 int (*capget) (struct task_struct *target,
@@ -1739,6 +1766,13 @@ extern void __init security_fixup_ops(struct security_operations *ops);
1739 1766
1740 1767
1741/* Security operations */ 1768/* Security operations */
1769int security_binder_set_context_mgr(struct task_struct *mgr);
1770int security_binder_transaction(struct task_struct *from,
1771 struct task_struct *to);
1772int security_binder_transfer_binder(struct task_struct *from,
1773 struct task_struct *to);
1774int security_binder_transfer_file(struct task_struct *from,
1775 struct task_struct *to, struct file *file);
1742int security_ptrace_access_check(struct task_struct *child, unsigned int mode); 1776int security_ptrace_access_check(struct task_struct *child, unsigned int mode);
1743int security_ptrace_traceme(struct task_struct *parent); 1777int security_ptrace_traceme(struct task_struct *parent);
1744int security_capget(struct task_struct *target, 1778int security_capget(struct task_struct *target,
@@ -1927,6 +1961,30 @@ static inline int security_init(void)
1927 return 0; 1961 return 0;
1928} 1962}
1929 1963
1964static inline int security_binder_set_context_mgr(struct task_struct *mgr)
1965{
1966 return 0;
1967}
1968
1969static inline int security_binder_transaction(struct task_struct *from,
1970 struct task_struct *to)
1971{
1972 return 0;
1973}
1974
1975static inline int security_binder_transfer_binder(struct task_struct *from,
1976 struct task_struct *to)
1977{
1978 return 0;
1979}
1980
1981static inline int security_binder_transfer_file(struct task_struct *from,
1982 struct task_struct *to,
1983 struct file *file)
1984{
1985 return 0;
1986}
1987
1930static inline int security_ptrace_access_check(struct task_struct *child, 1988static inline int security_ptrace_access_check(struct task_struct *child,
1931 unsigned int mode) 1989 unsigned int mode)
1932{ 1990{
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 };