Skip to content

Commit 79af730

Browse files
stephensmalleygregkh
authored andcommitted
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 <[email protected]> Acked-by: Nick Kralevich <[email protected]> Acked-by: Jeffrey Vander Stoep <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 79563db commit 79af730

File tree

6 files changed

+209
-0
lines changed

6 files changed

+209
-0
lines changed

drivers/android/binder.c

+26
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <linux/vmalloc.h>
3838
#include <linux/slab.h>
3939
#include <linux/pid_namespace.h>
40+
#include <linux/security.h>
4041

4142
#ifdef CONFIG_ANDROID_BINDER_IPC_32BIT
4243
#define BINDER_IPC_32BIT 1
@@ -1400,6 +1401,11 @@ static void binder_transaction(struct binder_proc *proc,
14001401
return_error = BR_DEAD_REPLY;
14011402
goto err_dead_binder;
14021403
}
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+
}
14031409
if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack) {
14041410
struct binder_transaction *tmp;
14051411

@@ -1551,6 +1557,11 @@ static void binder_transaction(struct binder_proc *proc,
15511557
return_error = BR_FAILED_REPLY;
15521558
goto err_binder_get_ref_for_node_failed;
15531559
}
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+
}
15541565
ref = binder_get_ref_for_node(target_proc, node);
15551566
if (ref == NULL) {
15561567
return_error = BR_FAILED_REPLY;
@@ -1581,6 +1592,11 @@ static void binder_transaction(struct binder_proc *proc,
15811592
return_error = BR_FAILED_REPLY;
15821593
goto err_binder_get_ref_failed;
15831594
}
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+
}
15841600
if (ref->node->proc == target_proc) {
15851601
if (fp->type == BINDER_TYPE_HANDLE)
15861602
fp->type = BINDER_TYPE_BINDER;
@@ -1638,6 +1654,13 @@ static void binder_transaction(struct binder_proc *proc,
16381654
return_error = BR_FAILED_REPLY;
16391655
goto err_fget_failed;
16401656
}
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+
}
16411664
target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC);
16421665
if (target_fd < 0) {
16431666
fput(file);
@@ -2675,6 +2698,9 @@ static int binder_ioctl_set_ctx_mgr(struct file *filp)
26752698
ret = -EBUSY;
26762699
goto out;
26772700
}
2701+
ret = security_binder_set_context_mgr(proc->tsk);
2702+
if (ret < 0)
2703+
goto out;
26782704
if (uid_valid(binder_context_mgr_uid)) {
26792705
if (!uid_eq(binder_context_mgr_uid, curr_euid)) {
26802706
pr_err("BINDER_SET_CONTEXT_MGR bad uid %d != %d\n",

include/linux/security.h

+58
Original file line numberDiff line numberDiff line change
@@ -1281,6 +1281,25 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
12811281
* @alter contains the flag indicating whether changes are to be made.
12821282
* Return 0 if permission is granted.
12831283
*
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+
*
12841303
* @ptrace_access_check:
12851304
* Check permission before allowing the current process to trace the
12861305
* @child process.
@@ -1441,6 +1460,14 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
14411460
struct security_operations {
14421461
char name[SECURITY_NAME_MAX + 1];
14431462

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+
14441471
int (*ptrace_access_check) (struct task_struct *child, unsigned int mode);
14451472
int (*ptrace_traceme) (struct task_struct *parent);
14461473
int (*capget) (struct task_struct *target,
@@ -1739,6 +1766,13 @@ extern void __init security_fixup_ops(struct security_operations *ops);
17391766

17401767

17411768
/* Security operations */
1769+
int security_binder_set_context_mgr(struct task_struct *mgr);
1770+
int security_binder_transaction(struct task_struct *from,
1771+
struct task_struct *to);
1772+
int security_binder_transfer_binder(struct task_struct *from,
1773+
struct task_struct *to);
1774+
int security_binder_transfer_file(struct task_struct *from,
1775+
struct task_struct *to, struct file *file);
17421776
int security_ptrace_access_check(struct task_struct *child, unsigned int mode);
17431777
int security_ptrace_traceme(struct task_struct *parent);
17441778
int security_capget(struct task_struct *target,
@@ -1927,6 +1961,30 @@ static inline int security_init(void)
19271961
return 0;
19281962
}
19291963

1964+
static inline int security_binder_set_context_mgr(struct task_struct *mgr)
1965+
{
1966+
return 0;
1967+
}
1968+
1969+
static inline int security_binder_transaction(struct task_struct *from,
1970+
struct task_struct *to)
1971+
{
1972+
return 0;
1973+
}
1974+
1975+
static inline int security_binder_transfer_binder(struct task_struct *from,
1976+
struct task_struct *to)
1977+
{
1978+
return 0;
1979+
}
1980+
1981+
static 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+
19301988
static inline int security_ptrace_access_check(struct task_struct *child,
19311989
unsigned int mode)
19321990
{

security/capability.c

+27
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,29 @@
1212

1313
#include <linux/security.h>
1414

15+
static int cap_binder_set_context_mgr(struct task_struct *mgr)
16+
{
17+
return 0;
18+
}
19+
20+
static int cap_binder_transaction(struct task_struct *from,
21+
struct task_struct *to)
22+
{
23+
return 0;
24+
}
25+
26+
static int cap_binder_transfer_binder(struct task_struct *from,
27+
struct task_struct *to)
28+
{
29+
return 0;
30+
}
31+
32+
static int cap_binder_transfer_file(struct task_struct *from,
33+
struct task_struct *to, struct file *file)
34+
{
35+
return 0;
36+
}
37+
1538
static int cap_syslog(int type)
1639
{
1740
return 0;
@@ -930,6 +953,10 @@ static void cap_audit_rule_free(void *lsmrule)
930953

931954
void __init security_fixup_ops(struct security_operations *ops)
932955
{
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);
933960
set_to_cap_if_null(ops, ptrace_access_check);
934961
set_to_cap_if_null(ops, ptrace_traceme);
935962
set_to_cap_if_null(ops, capget);

security/security.c

+23
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,29 @@ int __init register_security(struct security_operations *ops)
135135

136136
/* Security operations */
137137

138+
int security_binder_set_context_mgr(struct task_struct *mgr)
139+
{
140+
return security_ops->binder_set_context_mgr(mgr);
141+
}
142+
143+
int security_binder_transaction(struct task_struct *from,
144+
struct task_struct *to)
145+
{
146+
return security_ops->binder_transaction(from, to);
147+
}
148+
149+
int 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+
155+
int 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+
138161
int security_ptrace_access_check(struct task_struct *child, unsigned int mode)
139162
{
140163
#ifdef CONFIG_SECURITY_YAMA_STACKED

security/selinux/hooks.c

+73
Original file line numberDiff line numberDiff line change
@@ -1933,6 +1933,74 @@ static inline u32 open_file_to_av(struct file *file)
19331933

19341934
/* Hook functions begin here. */
19351935

1936+
static 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+
1945+
static 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+
1964+
static 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+
1974+
static 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+
19362004
static int selinux_ptrace_access_check(struct task_struct *child,
19372005
unsigned int mode)
19382006
{
@@ -5810,6 +5878,11 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer)
58105878
static struct security_operations selinux_ops = {
58115879
.name = "selinux",
58125880

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+
58135886
.ptrace_access_check = selinux_ptrace_access_check,
58145887
.ptrace_traceme = selinux_ptrace_traceme,
58155888
.capget = selinux_capget,

security/selinux/include/classmap.h

+2
Original file line numberDiff line numberDiff line change
@@ -151,5 +151,7 @@ struct security_class_mapping secclass_map[] = {
151151
{ "kernel_service", { "use_as_override", "create_files_as", NULL } },
152152
{ "tun_socket",
153153
{ COMMON_SOCK_PERMS, "attach_queue", NULL } },
154+
{ "binder", { "impersonate", "call", "set_context_mgr", "transfer",
155+
NULL } },
154156
{ NULL }
155157
};

0 commit comments

Comments
 (0)