[PATCH 1/2] smack: fix bug: unprivileged task can create labels

Casey Schaufler casey at schaufler-ca.com
Fri Mar 7 17:45:19 UTC 2025


On 3/6/2025 2:43 PM, Konstantin Andreev wrote:
> If an unprivileged task is allowed to relabel itself
> (/smack/relabel-self is not empty),
> it can freely create new labels by writing their
> names into own /proc/PID/attr/smack/current
>
> This occurs because do_setattr() imports
> the provided label in advance,
> before checking "relabel-self" list.
>
> This change ensures that the "relabel-self" list
> is checked before importing the label.
>
> Fixes: 38416e53936e ("Smack: limited capability for changing process label")
> Signed-off-by: Konstantin Andreev <andreev at swemel.ru>
> ---
>  security/smack/smack_lsm.c | 41 +++++++++++++++++++++++++-------------
>  1 file changed, 27 insertions(+), 14 deletions(-)
>
> diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
> index 99833168604e..95a614ae4c9c 100644
> --- a/security/smack/smack_lsm.c
> +++ b/security/smack/smack_lsm.c
> @@ -3732,8 +3732,8 @@ static int do_setattr(u64 attr, void *value, size_t size)
>  	struct task_smack *tsp = smack_cred(current_cred());
>  	struct cred *new;
>  	struct smack_known *skp;
> -	struct smack_known_list_elem *sklep;
> -	int rc;
> +	char *labelstr;
> +	int rc = 0;
>  
>  	if (!smack_privileged(CAP_MAC_ADMIN) && list_empty(&tsp->smk_relabel))
>  		return -EPERM;
> @@ -3744,28 +3744,41 @@ static int do_setattr(u64 attr, void *value, size_t size)
>  	if (attr != LSM_ATTR_CURRENT)
>  		return -EOPNOTSUPP;
>  
> -	skp = smk_import_entry(value, size);
> -	if (IS_ERR(skp))
> -		return PTR_ERR(skp);
> +	labelstr = smk_parse_smack(value, size);
> +	if (IS_ERR(labelstr))
> +		return PTR_ERR(labelstr);
>  
>  	/*
>  	 * No process is ever allowed the web ("@") label
>  	 * and the star ("*") label.
>  	 */
> -	if (skp == &smack_known_web || skp == &smack_known_star)
> -		return -EINVAL;
> +	if (labelstr[1] == '\0' /* '@', '*' */) {
> +		const char c = labelstr[0];
> +
> +		if (c == *smack_known_web .smk_known ||

No space before ".smk_known". I can fix this if/when I take the patch.

> +		    c == *smack_known_star.smk_known) {
> +			rc = -EPERM;
> +			goto free_labelstr;
> +		}
> +	}
>  
>  	if (!smack_privileged(CAP_MAC_ADMIN)) {
> -		rc = -EPERM;
> +		const struct smack_known_list_elem *sklep;
>  		list_for_each_entry(sklep, &tsp->smk_relabel, list)
> -			if (sklep->smk_label == skp) {
> -				rc = 0;
> -				break;
> -			}
> -		if (rc)
> -			return rc;
> +			if (strcmp(sklep->smk_label->smk_known, labelstr) == 0)
> +				goto free_labelstr;
> +		rc = -EPERM;
>  	}
>  
> +free_labelstr:
> +	kfree(labelstr);
> +	if (rc)
> +		return -EPERM;
> +
> +	skp = smk_import_entry(value, size);
> +	if (IS_ERR(skp))
> +		return PTR_ERR(skp);
> +
>  	new = prepare_creds();
>  	if (new == NULL)
>  		return -ENOMEM;



More information about the Linux-security-module-archive mailing list