diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index dba17ea51ec0..3219aa24a822 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -815,6 +815,7 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size) struct selinux_fs_info *fsi = file_inode(file)->i_sb->s_fs_info; struct selinux_state *state = fsi->state; char *scon = NULL, *tcon = NULL; + char scon_onstack[256], tcon_onstack[256]; u32 ssid, tsid; u16 tclass; struct av_decision avd; @@ -826,15 +827,22 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size) if (length) goto out; - length = -ENOMEM; - scon = kzalloc(size + 1, GFP_KERNEL); - if (!scon) - goto out; + if (size + 1 > ARRAY_SIZE(scon_onstack)) { + length = -ENOMEM; + scon = kzalloc(size + 1, GFP_KERNEL); + if (!scon) + goto out; - length = -ENOMEM; - tcon = kzalloc(size + 1, GFP_KERNEL); - if (!tcon) - goto out; + length = -ENOMEM; + tcon = kzalloc(size + 1, GFP_KERNEL); + if (!tcon) + goto out; + } else { + scon = scon_onstack; + tcon = tcon_onstack; + memset(scon_onstack, 0, size + 1); + memset(tcon_onstack, 0, size + 1); + } length = -EINVAL; if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) @@ -856,8 +864,10 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size) avd.auditallow, avd.auditdeny, avd.seqno, avd.flags); out: - kfree(tcon); - kfree(scon); + if (scon != scon_onstack) { + kfree(tcon); + kfree(scon); + } return length; }