aboutsummaryrefslogtreecommitdiffstats
path: root/security/smack/smackfs.c
diff options
context:
space:
mode:
authorAhmed S. Darwish <darwish.07@gmail.com>2008-03-13 15:32:34 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-03-13 16:11:43 -0400
commitb500ce8d24d1f14426643da5f6fada28c1f60533 (patch)
tree17b6084b29434a968f787e238548a843126e2ec3 /security/smack/smackfs.c
parent93d74463d018ddf05c169ad399e62e90e0f82fc0 (diff)
smackfs: do not trust `count' in inodes write()s
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> Acked-by: Casey Schaufler <casey@schaufler-ca.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'security/smack/smackfs.c')
-rw-r--r--security/smack/smackfs.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 358c92c1a153..afe7c9b0732a 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -81,10 +81,23 @@ static struct semaphore smack_write_sem;
81/* 81/*
82 * Values for parsing cipso rules 82 * Values for parsing cipso rules
83 * SMK_DIGITLEN: Length of a digit field in a rule. 83 * SMK_DIGITLEN: Length of a digit field in a rule.
84 * SMK_CIPSOMEN: Minimum possible cipso rule length. 84 * SMK_CIPSOMIN: Minimum possible cipso rule length.
85 * SMK_CIPSOMAX: Maximum possible cipso rule length.
85 */ 86 */
86#define SMK_DIGITLEN 4 87#define SMK_DIGITLEN 4
87#define SMK_CIPSOMIN (SMK_MAXLEN + 2 * SMK_DIGITLEN) 88#define SMK_CIPSOMIN (SMK_LABELLEN + 2 * SMK_DIGITLEN)
89#define SMK_CIPSOMAX (SMK_CIPSOMIN + SMACK_CIPSO_MAXCATNUM * SMK_DIGITLEN)
90
91/*
92 * Values for parsing MAC rules
93 * SMK_ACCESS: Maximum possible combination of access permissions
94 * SMK_ACCESSLEN: Maximum length for a rule access field
95 * SMK_LOADLEN: Smack rule length
96 */
97#define SMK_ACCESS "rwxa"
98#define SMK_ACCESSLEN (sizeof(SMK_ACCESS) - 1)
99#define SMK_LOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN)
100
88 101
89/* 102/*
90 * Seq_file read operations for /smack/load 103 * Seq_file read operations for /smack/load
@@ -229,14 +242,10 @@ static void smk_set_access(struct smack_rule *srp)
229 * The format is exactly: 242 * The format is exactly:
230 * char subject[SMK_LABELLEN] 243 * char subject[SMK_LABELLEN]
231 * char object[SMK_LABELLEN] 244 * char object[SMK_LABELLEN]
232 * char access[SMK_ACCESSKINDS] 245 * char access[SMK_ACCESSLEN]
233 *
234 * Anything following is commentary and ignored.
235 * 246 *
236 * writes must be SMK_LABELLEN+SMK_LABELLEN+4 bytes. 247 * writes must be SMK_LABELLEN+SMK_LABELLEN+SMK_ACCESSLEN bytes.
237 */ 248 */
238#define MINIMUM_LOAD (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSKINDS)
239
240static ssize_t smk_write_load(struct file *file, const char __user *buf, 249static ssize_t smk_write_load(struct file *file, const char __user *buf,
241 size_t count, loff_t *ppos) 250 size_t count, loff_t *ppos)
242{ 251{
@@ -253,7 +262,7 @@ static ssize_t smk_write_load(struct file *file, const char __user *buf,
253 return -EPERM; 262 return -EPERM;
254 if (*ppos != 0) 263 if (*ppos != 0)
255 return -EINVAL; 264 return -EINVAL;
256 if (count < MINIMUM_LOAD) 265 if (count != SMK_LOADLEN)
257 return -EINVAL; 266 return -EINVAL;
258 267
259 data = kzalloc(count, GFP_KERNEL); 268 data = kzalloc(count, GFP_KERNEL);
@@ -513,7 +522,7 @@ static ssize_t smk_write_cipso(struct file *file, const char __user *buf,
513 return -EPERM; 522 return -EPERM;
514 if (*ppos != 0) 523 if (*ppos != 0)
515 return -EINVAL; 524 return -EINVAL;
516 if (count <= SMK_CIPSOMIN) 525 if (count < SMK_CIPSOMIN || count > SMK_CIPSOMAX)
517 return -EINVAL; 526 return -EINVAL;
518 527
519 data = kzalloc(count + 1, GFP_KERNEL); 528 data = kzalloc(count + 1, GFP_KERNEL);
@@ -547,7 +556,7 @@ static ssize_t smk_write_cipso(struct file *file, const char __user *buf,
547 if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM) 556 if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM)
548 goto out; 557 goto out;
549 558
550 if (count <= (SMK_CIPSOMIN + catlen * SMK_DIGITLEN)) 559 if (count != (SMK_CIPSOMIN + catlen * SMK_DIGITLEN))
551 goto out; 560 goto out;
552 561
553 memset(mapcatset, 0, sizeof(mapcatset)); 562 memset(mapcatset, 0, sizeof(mapcatset));