--- /dev/null
+From ff6a20175559e87b34d2b0457d32cd53b4ac7884 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Oct 2024 11:20:21 -0300
+Subject: selinux: improve error checking in sel_write_load()
+
+From: Paul Moore <paul@paul-moore.com>
+
+[ 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>
+Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/selinux/selinuxfs.c | 30 ++++++++++++++++--------------
+ 1 file changed, 16 insertions(+), 14 deletions(-)
+
+diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
+index 2c23a5a286086..54bc18e8164b3 100644
+--- a/security/selinux/selinuxfs.c
++++ b/security/selinux/selinuxfs.c
+@@ -582,11 +582,18 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+
+ {
+- struct selinux_fs_info *fsi = file_inode(file)->i_sb->s_fs_info;
++ struct selinux_fs_info *fsi;
+ struct selinux_load_state load_state;
+ ssize_t length;
+ void *data = NULL;
+
++ /* no partial writes */
++ if (*ppos)
++ return -EINVAL;
++ /* no empty policies */
++ if (!count)
++ return -EINVAL;
++
+ mutex_lock(&selinux_state.policy_mutex);
+
+ length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
+@@ -594,26 +601,22 @@ 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 = -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(data, count, &load_state);
+ if (length) {
+ pr_warn_ratelimited("SELinux: failed to load policy\n");
+ goto out;
+ }
+-
++ fsi = file_inode(file)->i_sb->s_fs_info;
+ length = sel_make_policy_nodes(fsi, load_state.policy);
+ if (length) {
+ pr_warn_ratelimited("SELinux: failed to initialize selinuxfs\n");
+@@ -622,13 +625,12 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
+ }
+
+ selinux_policy_commit(&load_state);
+-
+ length = count;
+-
+ audit_log(audit_context(), GFP_KERNEL, AUDIT_MAC_POLICY_LOAD,
+ "auid=%u ses=%u lsm=selinux res=1",
+ from_kuid(&init_user_ns, audit_get_loginuid(current)),
+ audit_get_sessionid(current));
++
+ out:
+ mutex_unlock(&selinux_state.policy_mutex);
+ vfree(data);
+--
+2.43.0
+