--- /dev/null
+From 3b64ec142b0237c1722da38144144252c2343bc0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Sep 2023 13:38:04 -0500
+Subject: cifs: Fix UAF in cifs_demultiplex_thread()
+
+From: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+
+[ Upstream commit d527f51331cace562393a8038d870b3e9916686f ]
+
+There is a UAF when xfstests on cifs:
+
+ BUG: KASAN: use-after-free in smb2_is_network_name_deleted+0x27/0x160
+ Read of size 4 at addr ffff88810103fc08 by task cifsd/923
+
+ CPU: 1 PID: 923 Comm: cifsd Not tainted 6.1.0-rc4+ #45
+ ...
+ Call Trace:
+ <TASK>
+ dump_stack_lvl+0x34/0x44
+ print_report+0x171/0x472
+ kasan_report+0xad/0x130
+ kasan_check_range+0x145/0x1a0
+ smb2_is_network_name_deleted+0x27/0x160
+ cifs_demultiplex_thread.cold+0x172/0x5a4
+ kthread+0x165/0x1a0
+ ret_from_fork+0x1f/0x30
+ </TASK>
+
+ Allocated by task 923:
+ kasan_save_stack+0x1e/0x40
+ kasan_set_track+0x21/0x30
+ __kasan_slab_alloc+0x54/0x60
+ kmem_cache_alloc+0x147/0x320
+ mempool_alloc+0xe1/0x260
+ cifs_small_buf_get+0x24/0x60
+ allocate_buffers+0xa1/0x1c0
+ cifs_demultiplex_thread+0x199/0x10d0
+ kthread+0x165/0x1a0
+ ret_from_fork+0x1f/0x30
+
+ Freed by task 921:
+ kasan_save_stack+0x1e/0x40
+ kasan_set_track+0x21/0x30
+ kasan_save_free_info+0x2a/0x40
+ ____kasan_slab_free+0x143/0x1b0
+ kmem_cache_free+0xe3/0x4d0
+ cifs_small_buf_release+0x29/0x90
+ SMB2_negotiate+0x8b7/0x1c60
+ smb2_negotiate+0x51/0x70
+ cifs_negotiate_protocol+0xf0/0x160
+ cifs_get_smb_ses+0x5fa/0x13c0
+ mount_get_conns+0x7a/0x750
+ cifs_mount+0x103/0xd00
+ cifs_smb3_do_mount+0x1dd/0xcb0
+ smb3_get_tree+0x1d5/0x300
+ vfs_get_tree+0x41/0xf0
+ path_mount+0x9b3/0xdd0
+ __x64_sys_mount+0x190/0x1d0
+ do_syscall_64+0x35/0x80
+ entry_SYSCALL_64_after_hwframe+0x46/0xb0
+
+The UAF is because:
+
+ mount(pid: 921) | cifsd(pid: 923)
+-------------------------------|-------------------------------
+ | cifs_demultiplex_thread
+SMB2_negotiate |
+ cifs_send_recv |
+ compound_send_recv |
+ smb_send_rqst |
+ wait_for_response |
+ wait_event_state [1] |
+ | standard_receive3
+ | cifs_handle_standard
+ | handle_mid
+ | mid->resp_buf = buf; [2]
+ | dequeue_mid [3]
+ KILL the process [4] |
+ resp_iov[i].iov_base = buf |
+ free_rsp_buf [5] |
+ | is_network_name_deleted [6]
+ | callback
+
+1. After send request to server, wait the response until
+ mid->mid_state != SUBMITTED;
+2. Receive response from server, and set it to mid;
+3. Set the mid state to RECEIVED;
+4. Kill the process, the mid state already RECEIVED, get 0;
+5. Handle and release the negotiate response;
+6. UAF.
+
+It can be easily reproduce with add some delay in [3] - [6].
+
+Only sync call has the problem since async call's callback is
+executed in cifsd process.
+
+Add an extra state to mark the mid state to READY before wakeup the
+waitter, then it can get the resp safely.
+
+Fixes: ec637e3ffb6b ("[CIFS] Avoid extra large buffer allocation (and memcpy) in cifs_readpages")
+Reviewed-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
+Signed-off-by: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/cifsglob.h | 1 +
+ fs/smb/client/transport.c | 34 +++++++++++++++++++++++-----------
+ 2 files changed, 24 insertions(+), 11 deletions(-)
+
+diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
+index 03f34ec63e10d..39602f39aea8f 100644
+--- a/fs/smb/client/cifsglob.h
++++ b/fs/smb/client/cifsglob.h
+@@ -1776,6 +1776,7 @@ static inline bool is_retryable_error(int error)
+ #define MID_RETRY_NEEDED 8 /* session closed while this request out */
+ #define MID_RESPONSE_MALFORMED 0x10
+ #define MID_SHUTDOWN 0x20
++#define MID_RESPONSE_READY 0x40 /* ready for other process handle the rsp */
+
+ /* Flags */
+ #define MID_WAIT_CANCELLED 1 /* Cancelled while waiting for response */
+diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c
+index e03ffcf7e201c..87aea456ee903 100644
+--- a/fs/smb/client/transport.c
++++ b/fs/smb/client/transport.c
+@@ -35,6 +35,8 @@
+ void
+ cifs_wake_up_task(struct mid_q_entry *mid)
+ {
++ if (mid->mid_state == MID_RESPONSE_RECEIVED)
++ mid->mid_state = MID_RESPONSE_READY;
+ wake_up_process(mid->callback_data);
+ }
+
+@@ -87,7 +89,8 @@ static void __release_mid(struct kref *refcount)
+ struct TCP_Server_Info *server = midEntry->server;
+
+ if (midEntry->resp_buf && (midEntry->mid_flags & MID_WAIT_CANCELLED) &&
+- midEntry->mid_state == MID_RESPONSE_RECEIVED &&
++ (midEntry->mid_state == MID_RESPONSE_RECEIVED ||
++ midEntry->mid_state == MID_RESPONSE_READY) &&
+ server->ops->handle_cancelled_mid)
+ server->ops->handle_cancelled_mid(midEntry, server);
+
+@@ -759,7 +762,8 @@ wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ)
+ int error;
+
+ error = wait_event_state(server->response_q,
+- midQ->mid_state != MID_REQUEST_SUBMITTED,
++ midQ->mid_state != MID_REQUEST_SUBMITTED &&
++ midQ->mid_state != MID_RESPONSE_RECEIVED,
+ (TASK_KILLABLE|TASK_FREEZABLE_UNSAFE));
+ if (error < 0)
+ return -ERESTARTSYS;
+@@ -912,7 +916,7 @@ cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
+
+ spin_lock(&server->mid_lock);
+ switch (mid->mid_state) {
+- case MID_RESPONSE_RECEIVED:
++ case MID_RESPONSE_READY:
+ spin_unlock(&server->mid_lock);
+ return rc;
+ case MID_RETRY_NEEDED:
+@@ -1011,6 +1015,9 @@ cifs_compound_callback(struct mid_q_entry *mid)
+ credits.instance = server->reconnect_instance;
+
+ add_credits(server, &credits, mid->optype);
++
++ if (mid->mid_state == MID_RESPONSE_RECEIVED)
++ mid->mid_state = MID_RESPONSE_READY;
+ }
+
+ static void
+@@ -1206,7 +1213,8 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
+ send_cancel(server, &rqst[i], midQ[i]);
+ spin_lock(&server->mid_lock);
+ midQ[i]->mid_flags |= MID_WAIT_CANCELLED;
+- if (midQ[i]->mid_state == MID_REQUEST_SUBMITTED) {
++ if (midQ[i]->mid_state == MID_REQUEST_SUBMITTED ||
++ midQ[i]->mid_state == MID_RESPONSE_RECEIVED) {
+ midQ[i]->callback = cifs_cancelled_callback;
+ cancelled_mid[i] = true;
+ credits[i].value = 0;
+@@ -1227,7 +1235,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
+ }
+
+ if (!midQ[i]->resp_buf ||
+- midQ[i]->mid_state != MID_RESPONSE_RECEIVED) {
++ midQ[i]->mid_state != MID_RESPONSE_READY) {
+ rc = -EIO;
+ cifs_dbg(FYI, "Bad MID state?\n");
+ goto out;
+@@ -1414,7 +1422,8 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
+ if (rc != 0) {
+ send_cancel(server, &rqst, midQ);
+ spin_lock(&server->mid_lock);
+- if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
++ if (midQ->mid_state == MID_REQUEST_SUBMITTED ||
++ midQ->mid_state == MID_RESPONSE_RECEIVED) {
+ /* no longer considered to be "in-flight" */
+ midQ->callback = release_mid;
+ spin_unlock(&server->mid_lock);
+@@ -1431,7 +1440,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
+ }
+
+ if (!midQ->resp_buf || !out_buf ||
+- midQ->mid_state != MID_RESPONSE_RECEIVED) {
++ midQ->mid_state != MID_RESPONSE_READY) {
+ rc = -EIO;
+ cifs_server_dbg(VFS, "Bad MID state?\n");
+ goto out;
+@@ -1555,14 +1564,16 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
+
+ /* Wait for a reply - allow signals to interrupt. */
+ rc = wait_event_interruptible(server->response_q,
+- (!(midQ->mid_state == MID_REQUEST_SUBMITTED)) ||
++ (!(midQ->mid_state == MID_REQUEST_SUBMITTED ||
++ midQ->mid_state == MID_RESPONSE_RECEIVED)) ||
+ ((server->tcpStatus != CifsGood) &&
+ (server->tcpStatus != CifsNew)));
+
+ /* Were we interrupted by a signal ? */
+ spin_lock(&server->srv_lock);
+ if ((rc == -ERESTARTSYS) &&
+- (midQ->mid_state == MID_REQUEST_SUBMITTED) &&
++ (midQ->mid_state == MID_REQUEST_SUBMITTED ||
++ midQ->mid_state == MID_RESPONSE_RECEIVED) &&
+ ((server->tcpStatus == CifsGood) ||
+ (server->tcpStatus == CifsNew))) {
+ spin_unlock(&server->srv_lock);
+@@ -1593,7 +1604,8 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
+ if (rc) {
+ send_cancel(server, &rqst, midQ);
+ spin_lock(&server->mid_lock);
+- if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
++ if (midQ->mid_state == MID_REQUEST_SUBMITTED ||
++ midQ->mid_state == MID_RESPONSE_RECEIVED) {
+ /* no longer considered to be "in-flight" */
+ midQ->callback = release_mid;
+ spin_unlock(&server->mid_lock);
+@@ -1613,7 +1625,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
+ return rc;
+
+ /* rcvd frame is ok */
+- if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_RECEIVED) {
++ if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_READY) {
+ rc = -EIO;
+ cifs_tcon_dbg(VFS, "Bad MID state?\n");
+ goto out;
+--
+2.40.1
+
--- /dev/null
+From d66755d46c76279c1b53c5f8977c551211a20af0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 3 Sep 2023 08:13:21 +0200
+Subject: gpio: tb10x: Fix an error handling path in tb10x_gpio_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit b547b5e52a0587e6b25ea520bf2f9e03d00cbcb6 ]
+
+If an error occurs after a successful irq_domain_add_linear() call, it
+should be undone by a corresponding irq_domain_remove(), as already done
+in the remove function.
+
+Fixes: c6ce2b6bffe5 ("gpio: add TB10x GPIO driver")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-tb10x.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/gpio-tb10x.c b/drivers/gpio/gpio-tb10x.c
+index de6afa3f97168..05357473d2a11 100644
+--- a/drivers/gpio/gpio-tb10x.c
++++ b/drivers/gpio/gpio-tb10x.c
+@@ -195,7 +195,7 @@ static int tb10x_gpio_probe(struct platform_device *pdev)
+ handle_edge_irq, IRQ_NOREQUEST, IRQ_NOPROBE,
+ IRQ_GC_INIT_MASK_CACHE);
+ if (ret)
+- return ret;
++ goto err_remove_domain;
+
+ gc = tb10x_gpio->domain->gc->gc[0];
+ gc->reg_base = tb10x_gpio->base;
+@@ -209,6 +209,10 @@ static int tb10x_gpio_probe(struct platform_device *pdev)
+ }
+
+ return 0;
++
++err_remove_domain:
++ irq_domain_remove(tb10x_gpio->domain);
++ return ret;
+ }
+
+ static int tb10x_gpio_remove(struct platform_device *pdev)
+--
+2.40.1
+
--- /dev/null
+From c3ae41e578ed47b04bcb2e3ab2ee21fc0c8f211e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Mar 2022 20:39:14 +0800
+Subject: i2c: mux: demux-pinctrl: check the return value of devm_kstrdup()
+
+From: Xiaoke Wang <xkernel.wang@foxmail.com>
+
+[ Upstream commit 7c0195fa9a9e263df204963f88a22b21688ffb66 ]
+
+devm_kstrdup() returns pointer to allocated string on success,
+NULL on failure. So it is better to check the return value of it.
+
+Fixes: e35478eac030 ("i2c: mux: demux-pinctrl: run properly with multiple instances")
+Signed-off-by: Xiaoke Wang <xkernel.wang@foxmail.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/muxes/i2c-demux-pinctrl.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/i2c/muxes/i2c-demux-pinctrl.c b/drivers/i2c/muxes/i2c-demux-pinctrl.c
+index f7a7405d4350a..8e8688e8de0fb 100644
+--- a/drivers/i2c/muxes/i2c-demux-pinctrl.c
++++ b/drivers/i2c/muxes/i2c-demux-pinctrl.c
+@@ -243,6 +243,10 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev)
+
+ props[i].name = devm_kstrdup(&pdev->dev, "status", GFP_KERNEL);
+ props[i].value = devm_kstrdup(&pdev->dev, "ok", GFP_KERNEL);
++ if (!props[i].name || !props[i].value) {
++ err = -ENOMEM;
++ goto err_rollback;
++ }
+ props[i].length = 3;
+
+ of_changeset_init(&priv->chan[i].chgset);
+--
+2.40.1
+
--- /dev/null
+From afe4d31fa65a21e995513afc19358708e8c75f4a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Mar 2023 12:29:51 +0800
+Subject: i2c: mux: gpio: Add missing fwnode_handle_put()
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit db6aee6083a56ac4a6cd1b08fff7938072bcd0a3 ]
+
+In i2c_mux_gpio_probe_fw(), we should add fwnode_handle_put()
+when break out of the iteration device_for_each_child_node()
+as it will automatically increase and decrease the refcounter.
+
+Fixes: 98b2b712bc85 ("i2c: i2c-mux-gpio: Enable this driver in ACPI land")
+Signed-off-by: Liang He <windhl@126.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/muxes/i2c-mux-gpio.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c
+index 73a23e117ebec..0930a51c8c7c0 100644
+--- a/drivers/i2c/muxes/i2c-mux-gpio.c
++++ b/drivers/i2c/muxes/i2c-mux-gpio.c
+@@ -105,8 +105,10 @@ static int i2c_mux_gpio_probe_fw(struct gpiomux *mux,
+
+ } else if (is_acpi_node(child)) {
+ rc = acpi_get_local_address(ACPI_HANDLE_FWNODE(child), values + i);
+- if (rc)
++ if (rc) {
++ fwnode_handle_put(child);
+ return dev_err_probe(dev, rc, "Cannot get address\n");
++ }
+ }
+
+ i++;
+--
+2.40.1
+
--- /dev/null
+From 0fc1ab77479d0211a1b53e6072d16d0b29a35c63 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Sep 2023 14:41:09 +0100
+Subject: i2c: xiic: Correct return value check for xiic_reinit()
+
+From: Daniel Scally <dan.scally@ideasonboard.com>
+
+[ Upstream commit 59851fb05d759f13662be143eff0aae605815b0e ]
+
+The error paths for xiic_reinit() return negative values on failure
+and 0 on success - this error message therefore is triggered on
+_success_ rather than failure. Correct the condition so it's only
+shown on failure as intended.
+
+Fixes: 8fa9c9388053 ("i2c: xiic: return value of xiic_reinit")
+Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
+Acked-by: Michal Simek <michal.simek@amd.com>
+Reviewed-by: Andi Shyti <andi.shyti@kernel.org>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-xiic.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c
+index b41a6709e47f2..b27bfc7765993 100644
+--- a/drivers/i2c/busses/i2c-xiic.c
++++ b/drivers/i2c/busses/i2c-xiic.c
+@@ -420,7 +420,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
+ * reset the IP instead of just flush fifos
+ */
+ ret = xiic_reinit(i2c);
+- if (!ret)
++ if (ret < 0)
+ dev_dbg(i2c->adap.dev.parent, "reinit failed\n");
+
+ if (i2c->rx_msg) {
+--
+2.40.1
+
--- /dev/null
+From 4e0c395209198f451085d5297a1efa1de504ac13 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Sep 2023 12:00:56 -0400
+Subject: proc: nommu: fix empty /proc/<pid>/maps
+
+From: Ben Wolsieffer <ben.wolsieffer@hefring.com>
+
+[ Upstream commit fe4419801617514765974f3e796269bc512ad146 ]
+
+On no-MMU, /proc/<pid>/maps reads as an empty file. This happens because
+find_vma(mm, 0) always returns NULL (assuming no vma actually contains the
+zero address, which is normally the case).
+
+To fix this bug and improve the maintainability in the future, this patch
+makes the no-MMU implementation as similar as possible to the MMU
+implementation.
+
+The only remaining differences are the lack of hold/release_task_mempolicy
+and the extra code to shoehorn the gate vma into the iterator.
+
+This has been tested on top of 6.5.3 on an STM32F746.
+
+Link: https://lkml.kernel.org/r/20230915160055.971059-2-ben.wolsieffer@hefring.com
+Fixes: 0c563f148043 ("proc: remove VMA rbtree use from nommu")
+Signed-off-by: Ben Wolsieffer <ben.wolsieffer@hefring.com>
+Cc: Davidlohr Bueso <dave@stgolabs.net>
+Cc: Giulio Benetti <giulio.benetti@benettiengineering.com>
+Cc: Liam R. Howlett <Liam.Howlett@oracle.com>
+Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
+Cc: Oleg Nesterov <oleg@redhat.com>
+Cc: Vlastimil Babka <vbabka@suse.cz>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/proc/internal.h | 2 --
+ fs/proc/task_nommu.c | 37 ++++++++++++++++++++++---------------
+ 2 files changed, 22 insertions(+), 17 deletions(-)
+
+diff --git a/fs/proc/internal.h b/fs/proc/internal.h
+index b701d0207edf0..6b921826d85b6 100644
+--- a/fs/proc/internal.h
++++ b/fs/proc/internal.h
+@@ -289,9 +289,7 @@ struct proc_maps_private {
+ struct inode *inode;
+ struct task_struct *task;
+ struct mm_struct *mm;
+-#ifdef CONFIG_MMU
+ struct vma_iterator iter;
+-#endif
+ #ifdef CONFIG_NUMA
+ struct mempolicy *task_mempolicy;
+ #endif
+diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
+index bfcf17f75ed50..dc05780f93e13 100644
+--- a/fs/proc/task_nommu.c
++++ b/fs/proc/task_nommu.c
+@@ -188,15 +188,28 @@ static int show_map(struct seq_file *m, void *_p)
+ return nommu_vma_show(m, _p);
+ }
+
+-static void *m_start(struct seq_file *m, loff_t *pos)
++static struct vm_area_struct *proc_get_vma(struct proc_maps_private *priv,
++ loff_t *ppos)
++{
++ struct vm_area_struct *vma = vma_next(&priv->iter);
++
++ if (vma) {
++ *ppos = vma->vm_start;
++ } else {
++ *ppos = -1UL;
++ }
++
++ return vma;
++}
++
++static void *m_start(struct seq_file *m, loff_t *ppos)
+ {
+ struct proc_maps_private *priv = m->private;
++ unsigned long last_addr = *ppos;
+ struct mm_struct *mm;
+- struct vm_area_struct *vma;
+- unsigned long addr = *pos;
+
+- /* See m_next(). Zero at the start or after lseek. */
+- if (addr == -1UL)
++ /* See proc_get_vma(). Zero at the start or after lseek. */
++ if (last_addr == -1UL)
+ return NULL;
+
+ /* pin the task and mm whilst we play with them */
+@@ -218,12 +231,9 @@ static void *m_start(struct seq_file *m, loff_t *pos)
+ return ERR_PTR(-EINTR);
+ }
+
+- /* start the next element from addr */
+- vma = find_vma(mm, addr);
+- if (vma)
+- return vma;
++ vma_iter_init(&priv->iter, mm, last_addr);
+
+- return NULL;
++ return proc_get_vma(priv, ppos);
+ }
+
+ static void m_stop(struct seq_file *m, void *v)
+@@ -240,12 +250,9 @@ static void m_stop(struct seq_file *m, void *v)
+ priv->task = NULL;
+ }
+
+-static void *m_next(struct seq_file *m, void *_p, loff_t *pos)
++static void *m_next(struct seq_file *m, void *_p, loff_t *ppos)
+ {
+- struct vm_area_struct *vma = _p;
+-
+- *pos = vma->vm_end;
+- return find_vma(vma->vm_mm, vma->vm_end);
++ return proc_get_vma(m->private, ppos);
+ }
+
+ static const struct seq_operations proc_pid_maps_ops = {
+--
+2.40.1
+
--- /dev/null
+From 7aa724a9e34de64c27a4c0be1f56b0489018b3de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Sep 2023 12:30:20 -0400
+Subject: proc: nommu: /proc/<pid>/maps: release mmap read lock
+
+From: Ben Wolsieffer <Ben.Wolsieffer@hefring.com>
+
+[ Upstream commit 578d7699e5c2add8c2e9549d9d75dfb56c460cb3 ]
+
+The no-MMU implementation of /proc/<pid>/map doesn't normally release
+the mmap read lock, because it uses !IS_ERR_OR_NULL(_vml) to determine
+whether to release the lock. Since _vml is NULL when the end of the
+mappings is reached, the lock is not released.
+
+Reading /proc/1/maps twice doesn't cause a hang because it only
+takes the read lock, which can be taken multiple times and therefore
+doesn't show any problem if the lock isn't released. Instead, you need
+to perform some operation that attempts to take the write lock after
+reading /proc/<pid>/maps. To actually reproduce the bug, compile the
+following code as 'proc_maps_bug':
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+int main(int argc, char *argv[]) {
+ void *buf;
+ sleep(1);
+ buf = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ puts("mmap returned");
+ return 0;
+}
+
+Then, run:
+
+ ./proc_maps_bug &; cat /proc/$!/maps; fg
+
+Without this patch, mmap() will hang and the command will never
+complete.
+
+This code was incorrectly adapted from the MMU implementation, which at
+the time released the lock in m_next() before returning the last entry.
+
+The MMU implementation has diverged further from the no-MMU version since
+then, so this patch brings their locking and error handling into sync,
+fixing the bug and hopefully avoiding similar issues in the future.
+
+Link: https://lkml.kernel.org/r/20230914163019.4050530-2-ben.wolsieffer@hefring.com
+Fixes: 47fecca15c09 ("fs/proc/task_nommu.c: don't use priv->task->mm")
+Signed-off-by: Ben Wolsieffer <ben.wolsieffer@hefring.com>
+Acked-by: Oleg Nesterov <oleg@redhat.com>
+Cc: Giulio Benetti <giulio.benetti@benettiengineering.com>
+Cc: Greg Ungerer <gerg@uclinux.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: fe4419801617 ("proc: nommu: fix empty /proc/<pid>/maps")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/proc/task_nommu.c | 27 +++++++++++++++------------
+ 1 file changed, 15 insertions(+), 12 deletions(-)
+
+diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
+index 2fd06f52b6a44..bfcf17f75ed50 100644
+--- a/fs/proc/task_nommu.c
++++ b/fs/proc/task_nommu.c
+@@ -205,11 +205,16 @@ static void *m_start(struct seq_file *m, loff_t *pos)
+ return ERR_PTR(-ESRCH);
+
+ mm = priv->mm;
+- if (!mm || !mmget_not_zero(mm))
++ if (!mm || !mmget_not_zero(mm)) {
++ put_task_struct(priv->task);
++ priv->task = NULL;
+ return NULL;
++ }
+
+ if (mmap_read_lock_killable(mm)) {
+ mmput(mm);
++ put_task_struct(priv->task);
++ priv->task = NULL;
+ return ERR_PTR(-EINTR);
+ }
+
+@@ -218,23 +223,21 @@ static void *m_start(struct seq_file *m, loff_t *pos)
+ if (vma)
+ return vma;
+
+- mmap_read_unlock(mm);
+- mmput(mm);
+ return NULL;
+ }
+
+-static void m_stop(struct seq_file *m, void *_vml)
++static void m_stop(struct seq_file *m, void *v)
+ {
+ struct proc_maps_private *priv = m->private;
++ struct mm_struct *mm = priv->mm;
+
+- if (!IS_ERR_OR_NULL(_vml)) {
+- mmap_read_unlock(priv->mm);
+- mmput(priv->mm);
+- }
+- if (priv->task) {
+- put_task_struct(priv->task);
+- priv->task = NULL;
+- }
++ if (!priv->task)
++ return;
++
++ mmap_read_unlock(mm);
++ mmput(mm);
++ put_task_struct(priv->task);
++ priv->task = NULL;
+ }
+
+ static void *m_next(struct seq_file *m, void *_p, loff_t *pos)
+--
+2.40.1
+
bnxt_en-flush-xdp-for-bnxt_poll_nitroa0-s-napi.patch
octeontx2-pf-do-xdp_do_flush-after-redirects.patch
igc-expose-tx-usecs-coalesce-setting-to-user.patch
+proc-nommu-proc-pid-maps-release-mmap-read-lock.patch
+proc-nommu-fix-empty-proc-pid-maps.patch
+cifs-fix-uaf-in-cifs_demultiplex_thread.patch
+gpio-tb10x-fix-an-error-handling-path-in-tb10x_gpio_.patch
+i2c-mux-demux-pinctrl-check-the-return-value-of-devm.patch
+i2c-mux-gpio-add-missing-fwnode_handle_put.patch
+i2c-xiic-correct-return-value-check-for-xiic_reinit.patch