diff options
Diffstat (limited to 'security/selinux/hooks.c')
| -rw-r--r-- | security/selinux/hooks.c | 102 | 
1 files changed, 81 insertions, 21 deletions
| diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 6da7532893a1..29c39e0b03ed 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -401,23 +401,14 @@ static int selinux_is_sblabel_mnt(struct super_block *sb)  {  	struct superblock_security_struct *sbsec = sb->s_security; -	if (sbsec->behavior == SECURITY_FS_USE_XATTR || -	    sbsec->behavior == SECURITY_FS_USE_TRANS || -	    sbsec->behavior == SECURITY_FS_USE_TASK) -		return 1; - -	/* Special handling for sysfs. Is genfs but also has setxattr handler*/ -	if (strncmp(sb->s_type->name, "sysfs", sizeof("sysfs")) == 0) -		return 1; - -	/* -	 * Special handling for rootfs. Is genfs but supports -	 * setting SELinux context on in-core inodes. -	 */ -	if (strncmp(sb->s_type->name, "rootfs", sizeof("rootfs")) == 0) -		return 1; - -	return 0; +	return sbsec->behavior == SECURITY_FS_USE_XATTR || +		sbsec->behavior == SECURITY_FS_USE_TRANS || +		sbsec->behavior == SECURITY_FS_USE_TASK || +		/* Special handling. Genfs but also in-core setxattr handler */ +		!strcmp(sb->s_type->name, "sysfs") || +		!strcmp(sb->s_type->name, "pstore") || +		!strcmp(sb->s_type->name, "debugfs") || +		!strcmp(sb->s_type->name, "rootfs");  }  static int sb_finish_set_opts(struct super_block *sb) @@ -456,10 +447,6 @@ static int sb_finish_set_opts(struct super_block *sb)  	if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors))  		printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n",  		       sb->s_id, sb->s_type->name); -	else -		printk(KERN_DEBUG "SELinux: initialized (dev %s, type %s), %s\n", -		       sb->s_id, sb->s_type->name, -		       labeling_behaviors[sbsec->behavior-1]);  	sbsec->flags |= SE_SBINITIALIZED;  	if (selinux_is_sblabel_mnt(sb)) @@ -1933,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)  { @@ -5810,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, |