--- /dev/null
+From 659c0ce1cb9efc7f58d380ca4bb2a51ae9e30553 Mon Sep 17 00:00:00 2001
+From: Ondrej Mosnacek <omosnace@redhat.com>
+Date: Fri, 17 Feb 2023 17:21:54 +0100
+Subject: kernel/sys.c: fix and improve control flow in __sys_setres[ug]id()
+
+From: Ondrej Mosnacek <omosnace@redhat.com>
+
+commit 659c0ce1cb9efc7f58d380ca4bb2a51ae9e30553 upstream.
+
+Linux Security Modules (LSMs) that implement the "capable" hook will
+usually emit an access denial message to the audit log whenever they
+"block" the current task from using the given capability based on their
+security policy.
+
+The occurrence of a denial is used as an indication that the given task
+has attempted an operation that requires the given access permission, so
+the callers of functions that perform LSM permission checks must take care
+to avoid calling them too early (before it is decided if the permission is
+actually needed to perform the requested operation).
+
+The __sys_setres[ug]id() functions violate this convention by first
+calling ns_capable_setid() and only then checking if the operation
+requires the capability or not. It means that any caller that has the
+capability granted by DAC (task's capability set) but not by MAC (LSMs)
+will generate a "denied" audit record, even if is doing an operation for
+which the capability is not required.
+
+Fix this by reordering the checks such that ns_capable_setid() is checked
+last and -EPERM is returned immediately if it returns false.
+
+While there, also do two small optimizations:
+* move the capability check before prepare_creds() and
+* bail out early in case of a no-op.
+
+Link: https://lkml.kernel.org/r/20230217162154.837549-1-omosnace@redhat.com
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
+Cc: Eric W. Biederman <ebiederm@xmission.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/sys.c | 69 ++++++++++++++++++++++++++++++++++-------------------------
+ 1 file changed, 40 insertions(+), 29 deletions(-)
+
+--- a/kernel/sys.c
++++ b/kernel/sys.c
+@@ -656,6 +656,7 @@ long __sys_setresuid(uid_t ruid, uid_t e
+ struct cred *new;
+ int retval;
+ kuid_t kruid, keuid, ksuid;
++ bool ruid_new, euid_new, suid_new;
+
+ kruid = make_kuid(ns, ruid);
+ keuid = make_kuid(ns, euid);
+@@ -670,25 +671,29 @@ long __sys_setresuid(uid_t ruid, uid_t e
+ if ((suid != (uid_t) -1) && !uid_valid(ksuid))
+ return -EINVAL;
+
++ old = current_cred();
++
++ /* check for no-op */
++ if ((ruid == (uid_t) -1 || uid_eq(kruid, old->uid)) &&
++ (euid == (uid_t) -1 || (uid_eq(keuid, old->euid) &&
++ uid_eq(keuid, old->fsuid))) &&
++ (suid == (uid_t) -1 || uid_eq(ksuid, old->suid)))
++ return 0;
++
++ ruid_new = ruid != (uid_t) -1 && !uid_eq(kruid, old->uid) &&
++ !uid_eq(kruid, old->euid) && !uid_eq(kruid, old->suid);
++ euid_new = euid != (uid_t) -1 && !uid_eq(keuid, old->uid) &&
++ !uid_eq(keuid, old->euid) && !uid_eq(keuid, old->suid);
++ suid_new = suid != (uid_t) -1 && !uid_eq(ksuid, old->uid) &&
++ !uid_eq(ksuid, old->euid) && !uid_eq(ksuid, old->suid);
++ if ((ruid_new || euid_new || suid_new) &&
++ !ns_capable_setid(old->user_ns, CAP_SETUID))
++ return -EPERM;
++
+ new = prepare_creds();
+ if (!new)
+ return -ENOMEM;
+
+- old = current_cred();
+-
+- retval = -EPERM;
+- if (!ns_capable_setid(old->user_ns, CAP_SETUID)) {
+- if (ruid != (uid_t) -1 && !uid_eq(kruid, old->uid) &&
+- !uid_eq(kruid, old->euid) && !uid_eq(kruid, old->suid))
+- goto error;
+- if (euid != (uid_t) -1 && !uid_eq(keuid, old->uid) &&
+- !uid_eq(keuid, old->euid) && !uid_eq(keuid, old->suid))
+- goto error;
+- if (suid != (uid_t) -1 && !uid_eq(ksuid, old->uid) &&
+- !uid_eq(ksuid, old->euid) && !uid_eq(ksuid, old->suid))
+- goto error;
+- }
+-
+ if (ruid != (uid_t) -1) {
+ new->uid = kruid;
+ if (!uid_eq(kruid, old->uid)) {
+@@ -753,6 +758,7 @@ long __sys_setresgid(gid_t rgid, gid_t e
+ struct cred *new;
+ int retval;
+ kgid_t krgid, kegid, ksgid;
++ bool rgid_new, egid_new, sgid_new;
+
+ krgid = make_kgid(ns, rgid);
+ kegid = make_kgid(ns, egid);
+@@ -765,23 +771,28 @@ long __sys_setresgid(gid_t rgid, gid_t e
+ if ((sgid != (gid_t) -1) && !gid_valid(ksgid))
+ return -EINVAL;
+
++ old = current_cred();
++
++ /* check for no-op */
++ if ((rgid == (gid_t) -1 || gid_eq(krgid, old->gid)) &&
++ (egid == (gid_t) -1 || (gid_eq(kegid, old->egid) &&
++ gid_eq(kegid, old->fsgid))) &&
++ (sgid == (gid_t) -1 || gid_eq(ksgid, old->sgid)))
++ return 0;
++
++ rgid_new = rgid != (gid_t) -1 && !gid_eq(krgid, old->gid) &&
++ !gid_eq(krgid, old->egid) && !gid_eq(krgid, old->sgid);
++ egid_new = egid != (gid_t) -1 && !gid_eq(kegid, old->gid) &&
++ !gid_eq(kegid, old->egid) && !gid_eq(kegid, old->sgid);
++ sgid_new = sgid != (gid_t) -1 && !gid_eq(ksgid, old->gid) &&
++ !gid_eq(ksgid, old->egid) && !gid_eq(ksgid, old->sgid);
++ if ((rgid_new || egid_new || sgid_new) &&
++ !ns_capable_setid(old->user_ns, CAP_SETGID))
++ return -EPERM;
++
+ new = prepare_creds();
+ if (!new)
+ return -ENOMEM;
+- old = current_cred();
+-
+- retval = -EPERM;
+- if (!ns_capable_setid(old->user_ns, CAP_SETGID)) {
+- if (rgid != (gid_t) -1 && !gid_eq(krgid, old->gid) &&
+- !gid_eq(krgid, old->egid) && !gid_eq(krgid, old->sgid))
+- goto error;
+- if (egid != (gid_t) -1 && !gid_eq(kegid, old->gid) &&
+- !gid_eq(kegid, old->egid) && !gid_eq(kegid, old->sgid))
+- goto error;
+- if (sgid != (gid_t) -1 && !gid_eq(ksgid, old->gid) &&
+- !gid_eq(ksgid, old->egid) && !gid_eq(ksgid, old->sgid))
+- goto error;
+- }
+
+ if (rgid != (gid_t) -1)
+ new->gid = krgid;
--- /dev/null
+From 4b6d621c9d859ff89e68cebf6178652592676013 Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Sat, 1 Apr 2023 22:03:27 +0200
+Subject: memstick: fix memory leak if card device is never registered
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+commit 4b6d621c9d859ff89e68cebf6178652592676013 upstream.
+
+When calling dev_set_name() memory is allocated for the name for the
+struct device. Once that structure device is registered, or attempted
+to be registerd, with the driver core, the driver core will handle
+cleaning up that memory when the device is removed from the system.
+
+Unfortunatly for the memstick code, there is an error path that causes
+the struct device to never be registered, and so the memory allocated in
+dev_set_name will be leaked. Fix that leak by manually freeing it right
+before the memory for the device is freed.
+
+Cc: Maxim Levitsky <maximlevitsky@gmail.com>
+Cc: Alex Dubov <oakad@yahoo.com>
+Cc: Ulf Hansson <ulf.hansson@linaro.org>
+Cc: "Rafael J. Wysocki" <rafael@kernel.org>
+Cc: Hans de Goede <hdegoede@redhat.com>
+Cc: Kay Sievers <kay.sievers@vrfy.org>
+Cc: linux-mmc@vger.kernel.org
+Fixes: 0252c3b4f018 ("memstick: struct device - replace bus_id with dev_name(), dev_set_name()")
+Cc: stable <stable@kernel.org>
+Co-developed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Co-developed-by: Mirsad Goran Todorovac <mirsad.todorovac@alu.unizg.hr>
+Signed-off-by: Mirsad Goran Todorovac <mirsad.todorovac@alu.unizg.hr>
+Link: https://lore.kernel.org/r/20230401200327.16800-1-gregkh@linuxfoundation.org
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/memstick/core/memstick.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/memstick/core/memstick.c
++++ b/drivers/memstick/core/memstick.c
+@@ -410,6 +410,7 @@ static struct memstick_dev *memstick_all
+ return card;
+ err_out:
+ host->card = old_card;
++ kfree_const(card->dev.kobj.name);
+ kfree(card);
+ return NULL;
+ }
+@@ -468,8 +469,10 @@ static void memstick_check(struct work_s
+ put_device(&card->dev);
+ host->card = NULL;
+ }
+- } else
++ } else {
++ kfree_const(card->dev.kobj.name);
+ kfree(card);
++ }
+ }
+
+ out_power_off:
--- /dev/null
+From ef832747a82dfbc22a3702219cc716f449b24e4a Mon Sep 17 00:00:00 2001
+From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Date: Tue, 18 Apr 2023 02:35:13 +0900
+Subject: nilfs2: initialize unused bytes in segment summary blocks
+
+From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+
+commit ef832747a82dfbc22a3702219cc716f449b24e4a upstream.
+
+Syzbot still reports uninit-value in nilfs_add_checksums_on_logs() for
+KMSAN enabled kernels after applying commit 7397031622e0 ("nilfs2:
+initialize "struct nilfs_binfo_dat"->bi_pad field").
+
+This is because the unused bytes at the end of each block in segment
+summaries are not initialized. So this fixes the issue by padding the
+unused bytes with null bytes.
+
+Link: https://lkml.kernel.org/r/20230417173513.12598-1-konishi.ryusuke@gmail.com
+Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Tested-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Reported-by: syzbot+048585f3f4227bb2b49b@syzkaller.appspotmail.com
+ Link: https://syzkaller.appspot.com/bug?extid=048585f3f4227bb2b49b
+Cc: Alexander Potapenko <glider@google.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nilfs2/segment.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+--- a/fs/nilfs2/segment.c
++++ b/fs/nilfs2/segment.c
+@@ -430,6 +430,23 @@ static int nilfs_segctor_reset_segment_b
+ return 0;
+ }
+
++/**
++ * nilfs_segctor_zeropad_segsum - zero pad the rest of the segment summary area
++ * @sci: segment constructor object
++ *
++ * nilfs_segctor_zeropad_segsum() zero-fills unallocated space at the end of
++ * the current segment summary block.
++ */
++static void nilfs_segctor_zeropad_segsum(struct nilfs_sc_info *sci)
++{
++ struct nilfs_segsum_pointer *ssp;
++
++ ssp = sci->sc_blk_cnt > 0 ? &sci->sc_binfo_ptr : &sci->sc_finfo_ptr;
++ if (ssp->offset < ssp->bh->b_size)
++ memset(ssp->bh->b_data + ssp->offset, 0,
++ ssp->bh->b_size - ssp->offset);
++}
++
+ static int nilfs_segctor_feed_segment(struct nilfs_sc_info *sci)
+ {
+ sci->sc_nblk_this_inc += sci->sc_curseg->sb_sum.nblocks;
+@@ -438,6 +455,7 @@ static int nilfs_segctor_feed_segment(st
+ * The current segment is filled up
+ * (internal code)
+ */
++ nilfs_segctor_zeropad_segsum(sci);
+ sci->sc_curseg = NILFS_NEXT_SEGBUF(sci->sc_curseg);
+ return nilfs_segctor_reset_segment_buffer(sci);
+ }
+@@ -542,6 +560,7 @@ static int nilfs_segctor_add_file_block(
+ goto retry;
+ }
+ if (unlikely(required)) {
++ nilfs_segctor_zeropad_segsum(sci);
+ err = nilfs_segbuf_extend_segsum(segbuf);
+ if (unlikely(err))
+ goto failed;
+@@ -1531,6 +1550,7 @@ static int nilfs_segctor_collect(struct
+ nadd = min_t(int, nadd << 1, SC_MAX_SEGDELTA);
+ sci->sc_stage = prev_stage;
+ }
++ nilfs_segctor_zeropad_segsum(sci);
+ nilfs_segctor_truncate_segments(sci, sci->sc_curseg, nilfs->ns_sufile);
+ return 0;
+