]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 8 Jan 2026 13:25:27 +0000 (14:25 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 8 Jan 2026 13:25:27 +0000 (14:25 +0100)
added patches:
nfs-localio-fix-regression-due-to-out-of-order-__put_cred.patch

queue-6.18/nfs-localio-fix-regression-due-to-out-of-order-__put_cred.patch [new file with mode: 0644]
queue-6.18/series

diff --git a/queue-6.18/nfs-localio-fix-regression-due-to-out-of-order-__put_cred.patch b/queue-6.18/nfs-localio-fix-regression-due-to-out-of-order-__put_cred.patch
new file mode 100644 (file)
index 0000000..b8675e9
--- /dev/null
@@ -0,0 +1,100 @@
+From 3af870aedbff10bfed220e280b57a405e972229f Mon Sep 17 00:00:00 2001
+From: Mike Snitzer <snitzer@kernel.org>
+Date: Wed, 26 Nov 2025 01:01:25 -0500
+Subject: nfs/localio: fix regression due to out-of-order __put_cred
+
+From: Mike Snitzer <snitzer@kernel.org>
+
+commit 3af870aedbff10bfed220e280b57a405e972229f upstream.
+
+Commit f2060bdc21d7 ("nfs/localio: add refcounting for each iocb IO
+associated with NFS pgio header") inadvertantly reintroduced the same
+potential for __put_cred() triggering BUG_ON(cred == current->cred) that
+commit 992203a1fba5 ("nfs/localio: restore creds before releasing pageio
+data") fixed.
+
+Fix this by saving and restoring the cred around each {read,write}_iter
+call within the respective for loop of nfs_local_call_{read,write} using
+scoped_with_creds().
+
+NOTE: this fix started by first reverting the following commits:
+
+ 94afb627dfc2 ("nfs: use credential guards in nfs_local_call_read()")
+ bff3c841f7bd ("nfs: use credential guards in nfs_local_call_write()")
+ 1d18101a644e ("Merge tag 'kernel-6.19-rc1.cred' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs")
+
+followed by narrowly fixing the cred lifetime issue by using
+scoped_with_creds().  In doing so, this commit's changes appear more
+extensive than they really are (as evidenced by comparing to v6.18's
+fs/nfs/localio.c).
+
+Reported-by: Zorro Lang <zlang@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Acked-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Reviewed-by: Christian Brauner <brauner@kernel.org>
+Link: https://lore.kernel.org/linux-next/20251205111942.4150b06f@canb.auug.org.au/
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nfs/localio.c |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/fs/nfs/localio.c
++++ b/fs/nfs/localio.c
+@@ -623,8 +623,6 @@ static void nfs_local_call_read(struct w
+       ssize_t status;
+       int n_iters;
+-      save_cred = override_creds(filp->f_cred);
+-
+       n_iters = atomic_read(&iocb->n_iters);
+       for (int i = 0; i < n_iters ; i++) {
+               if (iocb->iter_is_dio_aligned[i]) {
+@@ -637,7 +635,10 @@ static void nfs_local_call_read(struct w
+               } else
+                       iocb->kiocb.ki_flags &= ~IOCB_DIRECT;
++              save_cred = override_creds(filp->f_cred);
+               status = filp->f_op->read_iter(&iocb->kiocb, &iocb->iters[i]);
++              revert_creds(save_cred);
++
+               if (status != -EIOCBQUEUED) {
+                       if (unlikely(status >= 0 && status < iocb->iters[i].count))
+                               force_done = true; /* Partial read */
+@@ -647,8 +648,6 @@ static void nfs_local_call_read(struct w
+                       }
+               }
+       }
+-
+-      revert_creds(save_cred);
+ }
+ static int
+@@ -830,7 +829,6 @@ static void nfs_local_call_write(struct
+       int n_iters;
+       current->flags |= PF_LOCAL_THROTTLE | PF_MEMALLOC_NOIO;
+-      save_cred = override_creds(filp->f_cred);
+       file_start_write(filp);
+       n_iters = atomic_read(&iocb->n_iters);
+@@ -845,7 +843,10 @@ static void nfs_local_call_write(struct
+               } else
+                       iocb->kiocb.ki_flags &= ~IOCB_DIRECT;
++              save_cred = override_creds(filp->f_cred);
+               status = filp->f_op->write_iter(&iocb->kiocb, &iocb->iters[i]);
++              revert_creds(save_cred);
++
+               if (status != -EIOCBQUEUED) {
+                       if (unlikely(status >= 0 && status < iocb->iters[i].count))
+                               force_done = true; /* Partial write */
+@@ -857,7 +858,6 @@ static void nfs_local_call_write(struct
+       }
+       file_end_write(filp);
+-      revert_creds(save_cred);
+       current->flags = old_flags;
+ }
index c4f94043348188ccdc1f851959252be99f2cc9c8..bf0423e8c834747512f0004c98fa97150b412cb2 100644 (file)
@@ -2,3 +2,4 @@ mptcp-ensure-context-reset-on-disconnect.patch
 sched-fair-small-cleanup-to-sched_balance_newidle.patch
 sched-fair-small-cleanup-to-update_newidle_cost.patch
 sched-fair-proportional-newidle-balance.patch
+nfs-localio-fix-regression-due-to-out-of-order-__put_cred.patch