From: Paul Moore paul@paul-moore.com
stable inclusion from stable-v4.19.323 commit acc599ee46881a9d377c33e7848e6bb2d97ef862 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBCC6Z CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
[ Upstream commit 42c773238037c90b3302bf37a57ae3b5c3f6004a ]
Move our existing input sanity checking to the top of sel_write_load() and add a check to ensure the buffer size is non-zero.
Move a local variable initialization from the declaration to before it is used.
Minor style adjustments.
Reported-by: Sam Sun samsun1006219@gmail.com Signed-off-by: Paul Moore paul@paul-moore.com [cascardo: keep fsi initialization at its declaration point as it is used earlier] [cascardo: keep check for 64MiB size limit] Signed-off-by: Thadeu Lima de Souza Cascardo cascardo@igalia.com Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Gu Bowen gubowen5@huawei.com --- security/selinux/selinuxfs.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-)
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index c1f8b18fa27b..d342c08cdd2b 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -536,6 +536,16 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf, ssize_t length; void *data = NULL;
+ /* no partial writes */ + if (*ppos) + return -EINVAL; + /* no empty policies */ + if (!count) + return -EINVAL; + + if (count > 64 * 1024 * 1024) + return -EFBIG; + mutex_lock(&fsi->mutex);
length = avc_has_perm(&selinux_state, @@ -544,23 +554,15 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf, if (length) goto out;
- /* No partial writes. */ - length = -EINVAL; - if (*ppos != 0) - goto out; - - length = -EFBIG; - if (count > 64 * 1024 * 1024) - goto out; - - length = -ENOMEM; data = vmalloc(count); - if (!data) + if (!data) { + length = -ENOMEM; goto out; - - length = -EFAULT; - if (copy_from_user(data, buf, count) != 0) + } + if (copy_from_user(data, buf, count) != 0) { + length = -EFAULT; goto out; + }
length = security_load_policy(fsi->state, data, count); if (length) { @@ -579,6 +581,7 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf, "auid=%u ses=%u lsm=selinux res=1", from_kuid(&init_user_ns, audit_get_loginuid(current)), audit_get_sessionid(current)); + out: mutex_unlock(&fsi->mutex); vfree(data);