Add security hooks to binder and implement the hooks for SELinux.
[cascardo/linux.git] / drivers / android / binder.c
index 8c43521..33b09b6 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
 #include <linux/pid_namespace.h>
+#include <linux/security.h>
 
 #ifdef CONFIG_ANDROID_BINDER_IPC_32BIT
 #define BINDER_IPC_32BIT 1
@@ -1400,6 +1401,11 @@ static void binder_transaction(struct binder_proc *proc,
                        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;
 
@@ -1551,6 +1557,11 @@ static void binder_transaction(struct binder_proc *proc,
                                return_error = BR_FAILED_REPLY;
                                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;
@@ -1581,6 +1592,11 @@ static void binder_transaction(struct binder_proc *proc,
                                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;
@@ -1638,6 +1654,13 @@ static void binder_transaction(struct binder_proc *proc,
                                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);
@@ -2675,6 +2698,9 @@ static int binder_ioctl_set_ctx_mgr(struct file *filp)
                ret = -EBUSY;
                goto out;
        }
+       ret = security_binder_set_context_mgr(proc->tsk);
+       if (ret < 0)
+               goto out;
        if (uid_valid(binder_context_mgr_uid)) {
                if (!uid_eq(binder_context_mgr_uid, curr_euid)) {
                        pr_err("BINDER_SET_CONTEXT_MGR bad uid %d != %d\n",