Skip to content

Commit c915297

Browse files
goongasUlrich Hecht
authored andcommitted
smack: fix bug: unprivileged task can create labels
[ Upstream commit c147e13ea7fe9f118f8c9ba5e96cbd644b00d6b3 ] 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: 38416e5 ("Smack: limited capability for changing process label") Signed-off-by: Konstantin Andreev <andreev@swemel.ru> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Ulrich Hecht <uli@kernel.org>
1 parent 5354a56 commit c915297

1 file changed

Lines changed: 27 additions & 14 deletions

File tree

security/smack/smack_lsm.c

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3655,8 +3655,8 @@ static int smack_setprocattr(const char *name, void *value, size_t size)
36553655
struct task_smack *tsp = current_security();
36563656
struct cred *new;
36573657
struct smack_known *skp;
3658-
struct smack_known_list_elem *sklep;
3659-
int rc;
3658+
char *labelstr;
3659+
int rc = 0;
36603660

36613661
if (!smack_privileged(CAP_MAC_ADMIN) && list_empty(&tsp->smk_relabel))
36623662
return -EPERM;
@@ -3667,28 +3667,41 @@ static int smack_setprocattr(const char *name, void *value, size_t size)
36673667
if (strcmp(name, "current") != 0)
36683668
return -EINVAL;
36693669

3670-
skp = smk_import_entry(value, size);
3671-
if (IS_ERR(skp))
3672-
return PTR_ERR(skp);
3670+
labelstr = smk_parse_smack(value, size);
3671+
if (IS_ERR(labelstr))
3672+
return PTR_ERR(labelstr);
36733673

36743674
/*
36753675
* No process is ever allowed the web ("@") label
36763676
* and the star ("*") label.
36773677
*/
3678-
if (skp == &smack_known_web || skp == &smack_known_star)
3679-
return -EINVAL;
3678+
if (labelstr[1] == '\0' /* '@', '*' */) {
3679+
const char c = labelstr[0];
3680+
3681+
if (c == *smack_known_web.smk_known ||
3682+
c == *smack_known_star.smk_known) {
3683+
rc = -EPERM;
3684+
goto free_labelstr;
3685+
}
3686+
}
36803687

36813688
if (!smack_privileged(CAP_MAC_ADMIN)) {
3682-
rc = -EPERM;
3689+
const struct smack_known_list_elem *sklep;
36833690
list_for_each_entry(sklep, &tsp->smk_relabel, list)
3684-
if (sklep->smk_label == skp) {
3685-
rc = 0;
3686-
break;
3687-
}
3688-
if (rc)
3689-
return rc;
3691+
if (strcmp(sklep->smk_label->smk_known, labelstr) == 0)
3692+
goto free_labelstr;
3693+
rc = -EPERM;
36903694
}
36913695

3696+
free_labelstr:
3697+
kfree(labelstr);
3698+
if (rc)
3699+
return -EPERM;
3700+
3701+
skp = smk_import_entry(value, size);
3702+
if (IS_ERR(skp))
3703+
return PTR_ERR(skp);
3704+
36923705
new = prepare_creds();
36933706
if (new == NULL)
36943707
return -ENOMEM;

0 commit comments

Comments
 (0)