rk312x: for the bug of suspend-resume
[firefly-linux-kernel-4.4.55.git] / security / selinux / hooks.c
index 70d4a8a7f21c1b996379fe59af3c7cca5aa087cd..e00585266536f5dbb35583d03f9b9ec272692ec5 100644 (file)
@@ -1856,6 +1856,67 @@ 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;
+       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)
 {
@@ -2672,6 +2733,7 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *na
 
 static noinline int audit_inode_permission(struct inode *inode,
                                           u32 perms, u32 audited, u32 denied,
+                                          int result,
                                           unsigned flags)
 {
        struct common_audit_data ad;
@@ -2682,7 +2744,7 @@ static noinline int audit_inode_permission(struct inode *inode,
        ad.u.inode = inode;
 
        rc = slow_avc_audit(current_sid(), isec->sid, isec->sclass, perms,
-                           audited, denied, &ad, flags);
+                           audited, denied, result, &ad, flags);
        if (rc)
                return rc;
        return 0;
@@ -2724,7 +2786,7 @@ static int selinux_inode_permission(struct inode *inode, int mask)
        if (likely(!audited))
                return rc;
 
-       rc2 = audit_inode_permission(inode, perms, audited, denied, flags);
+       rc2 = audit_inode_permission(inode, perms, audited, denied, rc, flags);
        if (rc2)
                return rc2;
        return rc;
@@ -5656,6 +5718,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,