smack: restrict smackfs/{direct,mapped} values to 0-255

Both smackfs/direct and smackfs/mapped incorrectly accept
the full range of integer values. For example:

    # cd /sys/fs/smackfs/
    # cat direct ; echo
    250

    # cat cipso2
    @ 250/2
    _ 250/2,4,5,6,7,8
    * 250/3,5,7
    ^ 250/2,4,5,6,7
    ? 250/3,4,5,6,7,8

    # echo -1234 >direct ; cat direct ; echo
    -1234
    # cat cipso2
    @ -1234/2
    _ -1234/2,4,5,6,7,8
    * -1234/3,5,7
    ^ -1234/2,4,5,6,7
    ? -1234/3,4,5,6,7,8
    #

I noticed two things regarding this:

1) sensitivity levels are truncated to 8 bits when labeling
   outgoing packets (0x2e = 46 for the -1234 example above)

2) the reverse process fails: incoming packets with sensitivity
   level 46 do not match these smackfs/cipso2 entries.

Even observation (1) on its own warrants a fix.

This patch restricts smackfs/direct and smackfs/mapped
accepted values to the 0-255 range.

Fixes: e114e47377 ("Smack: Simplified Mandatory Access Control Kernel")
Signed-off-by: Konstantin Andreev <andreev@swemel.ru>
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
This commit is contained in:
Konstantin Andreev 2026-05-25 01:37:49 +03:00 committed by Casey Schaufler
parent 577dc3b6a8
commit a7c44fd9f8
2 changed files with 15 additions and 13 deletions

View File

@ -318,7 +318,7 @@ int smack_populate_secattr(struct smack_known *skp);
* Shared data.
*/
extern int smack_enabled __initdata;
extern int smack_cipso_auto_level[2];
extern u8 smack_cipso_auto_level[2];
#define smack_cipso_direct (+smack_cipso_auto_level[0])
#define smack_cipso_mapped (+smack_cipso_auto_level[1])
extern struct smack_known *smack_net_ambient;

View File

@ -94,7 +94,7 @@ struct smack_known *smack_net_ambient;
* secid is contained directly in the category set.
* It can be reset via smackfs/mapped
*/
int smack_cipso_auto_level[2] = {
u8 smack_cipso_auto_level[2] = {
SMACK_CIPSO_DIRECT_DEFAULT,
SMACK_CIPSO_MAPPED_DEFAULT,
};
@ -1641,17 +1641,15 @@ static const struct file_operations smk_doi_ops = {
static ssize_t smk_read_cipso_auto_level(struct file *filp, char __user *buf,
size_t count, loff_t *ppos)
{
char temp[80];
ssize_t rc;
char temp[sizeof "255"];
int n;
if (*ppos != 0)
return 0;
sprintf(temp, "%d", smack_cipso_auto_level[
smk_cipso_auto_level_idx(filp)]);
rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
return rc;
n = sprintf(temp, "%u", (unsigned int)smack_cipso_auto_level[
smk_cipso_auto_level_idx(filp)]);
return simple_read_from_buffer(buf, count, ppos, temp, n);
}
/**
@ -1667,13 +1665,16 @@ static ssize_t
smk_write_cipso_auto_level(struct file *filp, const char __user *buf,
size_t count, loff_t *ppos)
{
struct smack_known *skp;
int i, ret, idx, old_lvl;
int ret, idx;
u8 i, old_lvl;
if (!smack_privileged(CAP_MAC_ADMIN))
return -EPERM;
ret = kstrtos32_from_user(buf, count, 10, &i);
/*
* draft-ietf-cipso-ipsecurity-01 (CIPSO 2.2), 3.4.2.4:
* "Sensitivity Level is 1 octet in length. Its value is from 0 to 255"
*/
ret = kstrtou8_from_user(buf, count, 10, &i);
if (unlikely(ret))
return ret;
@ -1686,6 +1687,7 @@ smk_write_cipso_auto_level(struct file *filp, const char __user *buf,
old_lvl = smack_cipso_auto_level[idx];
if (old_lvl != i) {
struct smack_known *skp;
mutex_lock(&smack_known_lock);
list_for_each_entry_rcu(skp, &smack_known_list, list)
if (skp->smk_netlabel.attr.mls.lvl ==