diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 79a8b3aceabe..254267f6cf92 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -1272,9 +1272,9 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent { struct superblock_security_struct *sbsec = NULL; struct inode_security_struct *isec = inode->i_security; + char context_onstack[SZ_4K] __aligned(sizeof(long)); u32 sid; struct dentry *dentry; -#define INITCONTEXTLEN 255 char *context = NULL; unsigned len = 0; int rc = 0; @@ -1329,19 +1329,11 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent goto out_unlock; } - len = INITCONTEXTLEN; - context = kmalloc(len+1, GFP_NOFS); - if (!context) { - rc = -ENOMEM; - dput(dentry); - goto out_unlock; - } - context[len] = '\0'; + context_onstack[ARRAY_SIZE(context_onstack) - 1] = '\0'; rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX, - context, len); + context_onstack, + ARRAY_SIZE(context_onstack)); if (rc == -ERANGE) { - kfree(context); - /* Need a larger buffer. Query for the right size. */ rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX, NULL, 0); @@ -1360,6 +1352,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX, context, len); + } else { + context = context_onstack; } dput(dentry); if (rc < 0) { @@ -1367,7 +1361,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent printk(KERN_WARNING "SELinux: %s: getxattr returned " "%d for dev=%s ino=%ld\n", __func__, -rc, inode->i_sb->s_id, inode->i_ino); - kfree(context); + if (context != context_onstack) + kfree(context); goto out_unlock; } /* Map ENODATA to the default file SID */ @@ -1391,13 +1386,15 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent "returned %d for dev=%s ino=%ld\n", __func__, context, -rc, dev, ino); } - kfree(context); + if (context != context_onstack) + kfree(context); /* Leave with the unlabeled SID */ rc = 0; break; } } - kfree(context); + if (context != context_onstack) + kfree(context); isec->sid = sid; break; case SECURITY_FS_USE_TASK: