diff options
Diffstat (limited to 'security/selinux/hooks.c')
| -rw-r--r-- | security/selinux/hooks.c | 82 | 
1 files changed, 44 insertions, 38 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 33fd061305c4..f5d304736852 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3,7 +3,7 @@   *   *  This file contains the SELinux hook function implementations.   * - *  Authors:  Stephen Smalley, <[email protected]> + *  Authors:  Stephen Smalley, <[email protected]>   *	      Chris Vance, <[email protected]>   *	      Wayne Salamon, <[email protected]>   *	      James Morris <[email protected]> @@ -815,7 +815,9 @@ static int selinux_set_mnt_opts(struct super_block *sb,  	if (!strcmp(sb->s_type->name, "debugfs") ||  	    !strcmp(sb->s_type->name, "tracefs") ||  	    !strcmp(sb->s_type->name, "sysfs") || -	    !strcmp(sb->s_type->name, "pstore")) +	    !strcmp(sb->s_type->name, "pstore") || +	    !strcmp(sb->s_type->name, "cgroup") || +	    !strcmp(sb->s_type->name, "cgroup2"))  		sbsec->flags |= SE_SBGENFS;  	if (!sbsec->behavior) { @@ -1303,6 +1305,7 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc  		case SOCK_SEQPACKET:  			return SECCLASS_UNIX_STREAM_SOCKET;  		case SOCK_DGRAM: +		case SOCK_RAW:  			return SECCLASS_UNIX_DGRAM_SOCKET;  		}  		break; @@ -2317,6 +2320,7 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm,  	int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS);  	int nosuid = !mnt_may_suid(bprm->file->f_path.mnt);  	int rc; +	u32 av;  	if (!nnp && !nosuid)  		return 0; /* neither NNP nor nosuid */ @@ -2325,24 +2329,40 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm,  		return 0; /* No change in credentials */  	/* -	 * The only transitions we permit under NNP or nosuid -	 * are transitions to bounded SIDs, i.e. SIDs that are -	 * guaranteed to only be allowed a subset of the permissions -	 * of the current SID. +	 * If the policy enables the nnp_nosuid_transition policy capability, +	 * then we permit transitions under NNP or nosuid if the +	 * policy allows the corresponding permission between +	 * the old and new contexts.  	 */ -	rc = security_bounded_transition(old_tsec->sid, new_tsec->sid); -	if (rc) { -		/* -		 * On failure, preserve the errno values for NNP vs nosuid. -		 * NNP:  Operation not permitted for caller. -		 * nosuid:  Permission denied to file. -		 */ +	if (selinux_policycap_nnp_nosuid_transition) { +		av = 0;  		if (nnp) -			return -EPERM; -		else -			return -EACCES; +			av |= PROCESS2__NNP_TRANSITION; +		if (nosuid) +			av |= PROCESS2__NOSUID_TRANSITION; +		rc = avc_has_perm(old_tsec->sid, new_tsec->sid, +				  SECCLASS_PROCESS2, av, NULL); +		if (!rc) +			return 0;  	} -	return 0; + +	/* +	 * We also permit NNP or nosuid transitions to bounded SIDs, +	 * i.e. SIDs that are guaranteed to only be allowed a subset +	 * of the permissions of the current SID. +	 */ +	rc = security_bounded_transition(old_tsec->sid, new_tsec->sid); +	if (!rc) +		return 0; + +	/* +	 * On failure, preserve the errno values for NNP vs nosuid. +	 * NNP:  Operation not permitted for caller. +	 * nosuid:  Permission denied to file. +	 */ +	if (nnp) +		return -EPERM; +	return -EACCES;  }  static int selinux_bprm_set_creds(struct linux_binprm *bprm) @@ -2356,7 +2376,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)  	/* SELinux context only depends on initial program or script and not  	 * the script interpreter */ -	if (bprm->cred_prepared) +	if (bprm->called_set_creds)  		return 0;  	old_tsec = current_security(); @@ -2442,30 +2462,17 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)  		/* Clear any possibly unsafe personality bits on exec: */  		bprm->per_clear |= PER_CLEAR_ON_SETID; -	} - -	return 0; -} -static int selinux_bprm_secureexec(struct linux_binprm *bprm) -{ -	const struct task_security_struct *tsec = current_security(); -	u32 sid, osid; -	int atsecure = 0; - -	sid = tsec->sid; -	osid = tsec->osid; - -	if (osid != sid) {  		/* Enable secure mode for SIDs transitions unless  		   the noatsecure permission is granted between  		   the two SIDs, i.e. ahp returns 0. */ -		atsecure = avc_has_perm(osid, sid, -					SECCLASS_PROCESS, -					PROCESS__NOATSECURE, NULL); +		rc = avc_has_perm(old_tsec->sid, new_tsec->sid, +				  SECCLASS_PROCESS, PROCESS__NOATSECURE, +				  NULL); +		bprm->secureexec |= !!rc;  	} -	return !!atsecure; +	return 0;  }  static int match_file(const void *p, struct file *file, unsigned fd) @@ -6266,7 +6273,6 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {  	LSM_HOOK_INIT(bprm_set_creds, selinux_bprm_set_creds),  	LSM_HOOK_INIT(bprm_committing_creds, selinux_bprm_committing_creds),  	LSM_HOOK_INIT(bprm_committed_creds, selinux_bprm_committed_creds), -	LSM_HOOK_INIT(bprm_secureexec, selinux_bprm_secureexec),  	LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security),  	LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security), @@ -6530,7 +6536,7 @@ security_initcall(selinux_init);  #if defined(CONFIG_NETFILTER) -static struct nf_hook_ops selinux_nf_ops[] = { +static const struct nf_hook_ops selinux_nf_ops[] = {  	{  		.hook =		selinux_ipv4_postroute,  		.pf =		NFPROTO_IPV4,  |