Merge tag 'char-misc-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregk...
[linux-drm-fsl-dcu.git] / security / selinux / hooks.c
index 87a915656eab61eb3c34638852ef2b91cdeee086..29c39e0b03ed7e3048d5fed858f31d40dc2f8d3d 100644 (file)
@@ -1920,6 +1920,74 @@ 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;
+       int rc;
+
+       ad.type = LSM_AUDIT_DATA_PATH;
+       ad.u.path = file->f_path;
+
+       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)
 {
@@ -5797,6 +5865,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,