selinux: Avoid dynamic memory allocation for INITCONTEXTLEN buffers

The default INITCONTEXTLEN-sized buffers can fit on the stack. Do so to
save a call to kmalloc() in a hot path.

Signed-off-by: Sultan Alsawaf <sultan@kerneltoast.com>
This commit is contained in:
Sultan Alsawaf 2021-02-06 19:51:14 -08:00 committed by spakkkk
parent f18743c5ae
commit 7375d8ee7a

View File

@ -1554,6 +1554,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
u16 sclass; u16 sclass;
struct dentry *dentry; struct dentry *dentry;
#define INITCONTEXTLEN 255 #define INITCONTEXTLEN 255
char context_onstack[INITCONTEXTLEN + 1];
char *context = NULL; char *context = NULL;
unsigned len = 0; unsigned len = 0;
int rc = 0; int rc = 0;
@ -1624,17 +1625,10 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
} }
len = INITCONTEXTLEN; len = INITCONTEXTLEN;
context = kmalloc(len+1, GFP_NOFS); context = context_onstack;
if (!context) {
rc = -ENOMEM;
dput(dentry);
goto out;
}
context[len] = '\0'; context[len] = '\0';
rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len); rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len);
if (rc == -ERANGE) { if (rc == -ERANGE) {
kfree(context);
/* Need a larger buffer. Query for the right size. */ /* Need a larger buffer. Query for the right size. */
rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, NULL, 0); rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, NULL, 0);
if (rc < 0) { if (rc < 0) {
@ -1657,7 +1651,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
pr_warn("SELinux: %s: getxattr returned " pr_warn("SELinux: %s: getxattr returned "
"%d for dev=%s ino=%ld\n", __func__, "%d for dev=%s ino=%ld\n", __func__,
-rc, inode->i_sb->s_id, inode->i_ino); -rc, inode->i_sb->s_id, inode->i_ino);
kfree(context); if (context != context_onstack)
kfree(context);
goto out; goto out;
} }
/* Map ENODATA to the default file SID */ /* Map ENODATA to the default file SID */
@ -1682,13 +1677,15 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
"returned %d for dev=%s ino=%ld\n", "returned %d for dev=%s ino=%ld\n",
__func__, context, -rc, dev, ino); __func__, context, -rc, dev, ino);
} }
kfree(context); if (context != context_onstack)
kfree(context);
/* Leave with the unlabeled SID */ /* Leave with the unlabeled SID */
rc = 0; rc = 0;
break; break;
} }
} }
kfree(context); if (context != context_onstack)
kfree(context);
break; break;
case SECURITY_FS_USE_TASK: case SECURITY_FS_USE_TASK:
sid = task_sid; sid = task_sid;