#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <linux/pid_namespace.h>
-#include <linux/security.h>
#include "binder.h"
#include "binder_trace.h"
return_error = BR_DEAD_REPLY;
goto err_dead_binder;
}
- if (security_binder_transaction(proc->tsk, target_proc->tsk) < 0) {
- return_error = BR_FAILED_REPLY;
- goto err_invalid_target_handle;
- }
if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack) {
struct binder_transaction *tmp;
tmp = thread->transaction_stack;
fp->cookie, node->cookie);
goto err_binder_get_ref_for_node_failed;
}
- if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) {
- return_error = BR_FAILED_REPLY;
- goto err_binder_get_ref_for_node_failed;
- }
ref = binder_get_ref_for_node(target_proc, node);
if (ref == NULL) {
return_error = BR_FAILED_REPLY;
return_error = BR_FAILED_REPLY;
goto err_binder_get_ref_failed;
}
- if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) {
- return_error = BR_FAILED_REPLY;
- goto err_binder_get_ref_failed;
- }
if (ref->node->proc == target_proc) {
if (fp->type == BINDER_TYPE_HANDLE)
fp->type = BINDER_TYPE_BINDER;
return_error = BR_FAILED_REPLY;
goto err_fget_failed;
}
- if (security_binder_transfer_file(proc->tsk, target_proc->tsk, file) < 0) {
- fput(file);
- return_error = BR_FAILED_REPLY;
- goto err_get_unused_fd_failed;
- }
target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC);
if (target_fd < 0) {
fput(file);
ret = -EBUSY;
goto err;
}
- ret = security_binder_set_context_mgr(proc->tsk);
- if (ret < 0)
- goto err;
if (uid_valid(binder_context_mgr_uid)) {
if (!uid_eq(binder_context_mgr_uid, current->cred->euid)) {
pr_err("BINDER_SET_CONTEXT_MGR bad uid %d != %d\n",
struct security_operations {
char name[SECURITY_NAME_MAX + 1];
- int (*binder_set_context_mgr) (struct task_struct *mgr);
- int (*binder_transaction) (struct task_struct *from, struct task_struct *to);
- int (*binder_transfer_binder) (struct task_struct *from, struct task_struct *to);
- int (*binder_transfer_file) (struct task_struct *from, struct task_struct *to, struct file *file);
-
int (*ptrace_access_check) (struct task_struct *child, unsigned int mode);
int (*ptrace_traceme) (struct task_struct *parent);
int (*capget) (struct task_struct *target,
/* Security operations */
-int security_binder_set_context_mgr(struct task_struct *mgr);
-int security_binder_transaction(struct task_struct *from, struct task_struct *to);
-int security_binder_transfer_binder(struct task_struct *from, struct task_struct *to);
-int security_binder_transfer_file(struct task_struct *from, struct task_struct *to, struct file *file);
int security_ptrace_access_check(struct task_struct *child, unsigned int mode);
int security_ptrace_traceme(struct task_struct *parent);
int security_capget(struct task_struct *target,
return 0;
}
-static inline int security_binder_set_context_mgr(struct task_struct *mgr)
-{
- return 0;
-}
-
-static inline int security_binder_transaction(struct task_struct *from, struct task_struct *to)
-{
- return 0;
-}
-
-static inline int security_binder_transfer_binder(struct task_struct *from, struct task_struct *to)
-{
- return 0;
-}
-
-static inline int security_binder_transfer_file(struct task_struct *from, struct task_struct *to, struct file *file)
-{
- return 0;
-}
-
static inline int security_ptrace_access_check(struct task_struct *child,
unsigned int mode)
{
#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;
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);
/* 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
/* 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;
-
- ad.type = LSM_AUDIT_DATA_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)
{
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,
{ "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 }
};