Smackfs: Do not trust `count' in inodes write()s
Subsystems (2)
PATCH 1/1 Smackfs: Do not trust `count' in inodes write()s
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.
---
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.
]
security/smack/smack.h +0 -8
@@ -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;
security/smack/smackfs.c +20 -11
@@ -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,
Signature · 5 lines
"Better to light a candle, than curse the darkness" Ahmed S. Darwish Homepage: http://darwish.07.googlepages.com Blog: http://darwish-07.blogspot.com
Quoted 6 lines · --- "Ahmed S. Darwish
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.
Quoted 7 lines
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 thatcount' does not exceed the size needed for a buffer representing maximum possible number of CIPSO 2.2 categories.Signed-off-by Ahmed S. Darwish <[email protected]>
One has trouble being too careful these days.
Quoted 111 lines
---
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.
]security/smack/smack.h +0
-8@@ -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;security/smack/smackfs.c +18
-9@@ -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, constchar __user *buf, return -EPERM;if (*ppos !=0 )return -EINVAL ; -if (count <MINIMUM_LOAD ) +if (count !=SMK_LOADLEN )return -EINVAL ;security/smack/smackfs.c +1
-1data =kzalloc (count,GFP_KERNEL );@@ -513,7 +522,7 @@ static ssize_t smk_write_cipso(struct file *file, constchar __user *buf, return -EPERM;if (*ppos !=0 )return -EINVAL ; -if (count <=SMK_CIPSOMIN ) +if (count <SMK_CIPSOMIN || count >SMK_CIPSOMAX )return -EINVAL ;security/smack/smackfs.c +1
-1data =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));
Quoted 12 lines
Regards,
Signature · 5 lines
"Better to light a candle, than curse the darkness" Ahmed S. Darwish Homepage: http://darwish.07.googlepages.com Blog: http://darwish-07.blogspot.com
Casey Schaufler
[email protected]