Skip to content

Commit

Permalink
smackfs: restrict bytes count in smackfs write functions
Browse files Browse the repository at this point in the history
commit 7ef4c19 upstream.

syzbot found WARNINGs in several smackfs write operations where
bytes count is passed to memdup_user_nul which exceeds
GFP MAX_ORDER. Check count size if bigger than PAGE_SIZE.

Per smackfs doc, smk_write_net4addr accepts any label or -CIPSO,
smk_write_net6addr accepts any label or -DELETE. I couldn't find
any general rule for other label lengths except SMK_LABELLEN,
SMK_LONGLABEL, SMK_CIPSOMAX which are documented.

Let's constrain, in general, smackfs label lengths for PAGE_SIZE.
Although fuzzer crashes write to smackfs/netlabel on 0x400000 length.

Here is a quick way to reproduce the WARNING:
python -c "print('A' * 0x400000)" > /sys/fs/smackfs/netlabel

Reported-by: syzbot+a71a442385a0b2815497@syzkaller.appspotmail.com
Signed-off-by: Sabyrzhan Tasbolatov <snovitoll@gmail.com>
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
novitoll authored and gregkh committed Mar 7, 2021
1 parent 5fe2446 commit 4ceb5ca
Showing 1 changed file with 19 additions and 2 deletions.
21 changes: 19 additions & 2 deletions security/smack/smackfs.c
Expand Up @@ -1163,7 +1163,7 @@ static ssize_t smk_write_net4addr(struct file *file, const char __user *buf,
return -EPERM;
if (*ppos != 0)
return -EINVAL;
if (count < SMK_NETLBLADDRMIN)
if (count < SMK_NETLBLADDRMIN || count > PAGE_SIZE - 1)
return -EINVAL;

data = memdup_user_nul(buf, count);
Expand Down Expand Up @@ -1423,7 +1423,7 @@ static ssize_t smk_write_net6addr(struct file *file, const char __user *buf,
return -EPERM;
if (*ppos != 0)
return -EINVAL;
if (count < SMK_NETLBLADDRMIN)
if (count < SMK_NETLBLADDRMIN || count > PAGE_SIZE - 1)
return -EINVAL;

data = memdup_user_nul(buf, count);
Expand Down Expand Up @@ -1830,6 +1830,10 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
if (!smack_privileged(CAP_MAC_ADMIN))
return -EPERM;

/* Enough data must be present */
if (count == 0 || count > PAGE_SIZE)
return -EINVAL;

data = memdup_user_nul(buf, count);
if (IS_ERR(data))
return PTR_ERR(data);
Expand Down Expand Up @@ -2001,6 +2005,9 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
if (!smack_privileged(CAP_MAC_ADMIN))
return -EPERM;

if (count > PAGE_SIZE)
return -EINVAL;

data = memdup_user_nul(buf, count);
if (IS_ERR(data))
return PTR_ERR(data);
Expand Down Expand Up @@ -2088,6 +2095,9 @@ static ssize_t smk_write_unconfined(struct file *file, const char __user *buf,
if (!smack_privileged(CAP_MAC_ADMIN))
return -EPERM;

if (count > PAGE_SIZE)
return -EINVAL;

data = memdup_user_nul(buf, count);
if (IS_ERR(data))
return PTR_ERR(data);
Expand Down Expand Up @@ -2643,6 +2653,10 @@ static ssize_t smk_write_syslog(struct file *file, const char __user *buf,
if (!smack_privileged(CAP_MAC_ADMIN))
return -EPERM;

/* Enough data must be present */
if (count == 0 || count > PAGE_SIZE)
return -EINVAL;

data = memdup_user_nul(buf, count);
if (IS_ERR(data))
return PTR_ERR(data);
Expand Down Expand Up @@ -2735,10 +2749,13 @@ static ssize_t smk_write_relabel_self(struct file *file, const char __user *buf,
return -EPERM;

/*
* No partial write.
* Enough data must be present.
*/
if (*ppos != 0)
return -EINVAL;
if (count == 0 || count > PAGE_SIZE)
return -EINVAL;

data = memdup_user_nul(buf, count);
if (IS_ERR(data))
Expand Down

0 comments on commit 4ceb5ca

Please sign in to comment.