From: "Ahmed S. Darwish" <darwish.07@gmail.com>
To: Casey Schaufler <casey@schaufler-ca.com>,
akpm <akpm@linux-foundation.org>
Cc: LKML <linux-kernel@vger.kernel.org>,
Linus <torvalds@linux-foundation.org>
Subject: [PATCH BUGFIX -rc4] Smackfs: Do not trust `count' in inodes write()s
Date: Sat, 8 Mar 2008 23:38:26 +0200 [thread overview]
Message-ID: <20080308213826.GA22536@ubuntu> (raw)
Hi all,
Smackfs write() implementation does not put a higher bound on the
number of bytes to copy from user-space. This may lead to a DOS
attack if a malicious `count' field is given.
Assure that given `count' is exactly the length needed for a
/smack/load rule. In case of /smack/cipso where the length is
relative, assure that `count' does not exceed the size needed for
a buffer representing maximum possible number of CIPSO 2.2
categories.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
---
smack.h | 8 --------
smackfs.c | 31 ++++++++++++++++++++-----------
2 files changed, 20 insertions(+), 19 deletions(-)
Smack user-space utilities (smackload, smackcipso) still work
fine after below change.
[
Who's responsible for forwarding Smack patches to Linus ?
I've CCed Andrew and Linus just in case.
]
diff --git a/security/smack/smack.h b/security/smack/smack.h
index c444f48..4a4477f 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -27,14 +27,6 @@
#define SMK_MAXLEN 23
#define SMK_LABELLEN (SMK_MAXLEN+1)
-/*
- * How many kinds of access are there?
- * Here's your answer.
- */
-#define SMK_ACCESSDASH '-'
-#define SMK_ACCESSLOW "rwxa"
-#define SMK_ACCESSKINDS (sizeof(SMK_ACCESSLOW) - 1)
-
struct superblock_smack {
char *smk_root;
char *smk_floor;
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index effd3de..3fc3a07 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -81,10 +81,23 @@ static struct semaphore smack_write_sem;
/*
* Values for parsing cipso rules
* SMK_DIGITLEN: Length of a digit field in a rule.
- * SMK_CIPSOMEN: Minimum possible cipso rule length.
+ * SMK_CIPSOMIN: Minimum possible cipso rule length.
+ * SMK_CIPSOMAX: Maximum possible cipso rule length.
*/
#define SMK_DIGITLEN 4
-#define SMK_CIPSOMIN (SMK_MAXLEN + 2 * SMK_DIGITLEN)
+#define SMK_CIPSOMIN (SMK_LABELLEN + 2 * SMK_DIGITLEN)
+#define SMK_CIPSOMAX (SMK_CIPSOMIN + SMACK_CIPSO_MAXCATNUM * SMK_DIGITLEN)
+
+/*
+ * Values for parsing MAC rules
+ * SMK_ACCESS: Maximum possible combination of access permissions
+ * SMK_ACCESSLEN: Maximum length for a rule access field
+ * SMK_LOADLEN: Smack rule length
+ */
+#define SMK_ACCESS "rwxa"
+#define SMK_ACCESSLEN (sizeof(SMK_ACCESS) - 1)
+#define SMK_LOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN)
+
/*
* Seq_file read operations for /smack/load
@@ -229,14 +242,10 @@ static void smk_set_access(struct smack_rule *srp)
* The format is exactly:
* char subject[SMK_LABELLEN]
* char object[SMK_LABELLEN]
- * char access[SMK_ACCESSKINDS]
- *
- * Anything following is commentary and ignored.
+ * char access[SMK_ACCESSLEN]
*
- * writes must be SMK_LABELLEN+SMK_LABELLEN+4 bytes.
+ * writes must be SMK_LABELLEN+SMK_LABELLEN+SMK_ACCESSLEN bytes.
*/
-#define MINIMUM_LOAD (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSKINDS)
-
static ssize_t smk_write_load(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
@@ -253,7 +262,7 @@ static ssize_t smk_write_load(struct file *file, const char __user *buf,
return -EPERM;
if (*ppos != 0)
return -EINVAL;
- if (count < MINIMUM_LOAD)
+ if (count != SMK_LOADLEN)
return -EINVAL;
data = kzalloc(count, GFP_KERNEL);
@@ -513,7 +522,7 @@ static ssize_t smk_write_cipso(struct file *file, const char __user *buf,
return -EPERM;
if (*ppos != 0)
return -EINVAL;
- if (count <= SMK_CIPSOMIN)
+ if (count < SMK_CIPSOMIN || count > SMK_CIPSOMAX)
return -EINVAL;
data = kzalloc(count + 1, GFP_KERNEL);
@@ -547,7 +556,7 @@ static ssize_t smk_write_cipso(struct file *file, const char __user *buf,
if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM)
goto out;
- if (count <= (SMK_CIPSOMIN + catlen * SMK_DIGITLEN))
+ if (count != (SMK_CIPSOMIN + catlen * SMK_DIGITLEN))
goto out;
memset(mapcatset, 0, sizeof(mapcatset));
Regards,
--
"Better to light a candle, than curse the darkness"
Ahmed S. Darwish
Homepage: http://darwish.07.googlepages.com
Blog: http://darwish-07.blogspot.com
next reply other threads:[~2008-03-08 21:41 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-03-08 21:38 Ahmed S. Darwish [this message]
2008-03-08 23:07 ` [PATCH BUGFIX -rc4] Smackfs: Do not trust `count' in inodes write()s Casey Schaufler
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080308213826.GA22536@ubuntu \
--to=darwish.07@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=casey@schaufler-ca.com \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.