FAILED: patch "[PATCH] NFSD: Hold net reference for the lifetime of" failed to apply to 5.10-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.10.y
git checkout FETCH_HEAD
git cherry-pick -x e7fcf179b82d3a3730fd8615da01b087cc654d0b
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026032042-stalling-batboy-6b82@gregkh' --subject-prefix 'PATCH 5.10.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From e7fcf179b82d3a3730fd8615da01b087cc654d0b Mon Sep 17 00:00:00 2001
From: Chuck Lever <[email protected]>
Date: Thu, 19 Feb 2026 16:50:17 -0500
Subject: [PATCH] NFSD: Hold net reference for the lifetime of
/proc/fs/nfs/exports fd
The /proc/fs/nfs/exports proc entry is created at module init and persists for the module's lifetime. exports_proc_open() captures the caller's current network namespace and stores its svc_export_cache in seq->private, but takes no reference on the namespace. If the namespace is subsequently torn down (e.g. container destruction after the opener does setns() to a different namespace), nfsd_net_exit() calls nfsd_export_shutdown() which frees the cache. Subsequent reads on the still-open fd dereference the freed cache_detail, walking a freed hash table.
Hold a reference on the struct net for the lifetime of the open file descriptor. This prevents nfsd_net_exit() from running -- and thus prevents nfsd_export_shutdown() from freeing the cache -- while any exports fd is open. cache_detail already stores its net pointer (cd->net, set by cache_create_net()), so exports_release() can retrieve it without additional per-file storage.
fs/nfsd/nfsctl.c +12 -2
@@ -149,9 +149,19 @@ static int exports_net_open(struct net *net, struct file *file) seq = file->private_data; seq->private = nn->svc_export_cache; +get_net (net);return 0 ; } +static int exports_release (struct inode *inode,struct file *file) +{ +struct seq_file *seq = file->private_data; +struct cache_detail *cd = seq->private; + +put_net (cd->net); +return seq_release (inode, file); +} +static int exports_nfsd_open (struct inode *inode,struct file *file) {return exports_net_open (inode->i_sb->s_fs_info, file);
@@ -161,7 +171,7 @@ static const struct file_operations exports_nfsd_operations = { .open = exports_nfsd_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = exports_release, };static int export_features_show (struct seq_file *m,void *v)
@@ -1376,7 +1386,7 @@ static const struct proc_ops exports_proc_ops = { .proc_open = exports_proc_open, .proc_read = seq_read, .proc_lseek = seq_lseek, - .proc_release = seq_release, + .proc_release = exports_release, };static int create_proc_exports_entry (void )
Sasha Levin
maintainerPATCH 1/2 nfsd: define exports_proc_ops with CONFIG_PROC_FS
From: Tom Rix <[email protected]>
[ Upstream commit 340086da9a87820b40601141a0e9e87c954ac006 ]
gcc with W=1 and ! CONFIG_PROC_FS fs/nfsd/nfsctl.c:161:30: error: ‘exports_proc_ops’
defined but not used [-Werror=unused-const-variable=]
161 | static const struct proc_ops exports_proc_ops = {
| ^~~~~~~~~~~~~~~~The only use of exports_proc_ops is when CONFIG_PROC_FS is defined, so its definition should be likewise conditional.
Stable-dep-of: e7fcf179b82d ("NFSD: Hold net reference for the lifetime of /proc/fs/nfs/exports fd")
--- fs/nfsd/nfsctl.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-)
fs/nfsd/nfsctl.c +13 -12
@@ -155,18 +155,6 @@ static int exports_net_open(struct net *net, struct file *file)return 0 ; } -static int exports_proc_open (struct inode *inode,struct file *file) -{ -return exports_net_open (current->nsproxy->net_ns, file); -} - -static const struct proc_ops exports_proc_ops = { - .proc_open = exports_proc_open, - .proc_read = seq_read, - .proc_lseek = seq_lseek, - .proc_release = seq_release, -}; -static int exports_nfsd_open (struct inode *inode,struct file *file) {return exports_net_open (inode->i_sb->s_fs_info, file);
@@ -1423,6 +1411,19 @@ static struct file_system_type nfsd_fs_type = {MODULE_ALIAS_FS ("nfsd" );#ifdef CONFIG_PROC_FS + +static int exports_proc_open (struct inode *inode,struct file *file) +{ +return exports_net_open (current->nsproxy->net_ns, file); +} + +static const struct proc_ops exports_proc_ops = { + .proc_open = exports_proc_open, + .proc_read = seq_read, + .proc_lseek = seq_lseek, + .proc_release = seq_release, +}; +static int create_proc_exports_entry (void ) {struct proc_dir_entry *entry;
Signature · 1 line
2.51.0
Sasha Levin
maintainerPATCH 2/2 NFSD: Hold net reference for the lifetime of /proc/fs/nfs/exports fd
From: Chuck Lever <[email protected]>
[ Upstream commit e7fcf179b82d3a3730fd8615da01b087cc654d0b ]
The /proc/fs/nfs/exports proc entry is created at module init and persists for the module's lifetime. exports_proc_open() captures the caller's current network namespace and stores its svc_export_cache in seq->private, but takes no reference on the namespace. If the namespace is subsequently torn down (e.g. container destruction after the opener does setns() to a different namespace), nfsd_net_exit() calls nfsd_export_shutdown() which frees the cache. Subsequent reads on the still-open fd dereference the freed cache_detail, walking a freed hash table.
Hold a reference on the struct net for the lifetime of the open file descriptor. This prevents nfsd_net_exit() from running -- and thus prevents nfsd_export_shutdown() from freeing the cache -- while any exports fd is open. cache_detail already stores its net pointer (cd->net, set by cache_create_net()), so exports_release() can retrieve it without additional per-file storage.
--- fs/nfsd/nfsctl.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
fs/nfsd/nfsctl.c +12 -2
@@ -152,9 +152,19 @@ static int exports_net_open(struct net *net, struct file *file) seq = file->private_data; seq->private = nn->svc_export_cache; +get_net (net);return 0 ; } +static int exports_release (struct inode *inode,struct file *file) +{ +struct seq_file *seq = file->private_data; +struct cache_detail *cd = seq->private; + +put_net (cd->net); +return seq_release (inode, file); +} +static int exports_nfsd_open (struct inode *inode,struct file *file) {return exports_net_open (inode->i_sb->s_fs_info, file);
@@ -164,7 +174,7 @@ static const struct file_operations exports_nfsd_operations = { .open = exports_nfsd_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = exports_release, };static int export_features_show (struct seq_file *m,void *v)
@@ -1421,7 +1431,7 @@ static const struct proc_ops exports_proc_ops = { .proc_open = exports_proc_open, .proc_read = seq_read, .proc_lseek = seq_lseek, - .proc_release = seq_release, + .proc_release = exports_release, };static int create_proc_exports_entry (void )
Signature · 1 line
2.51.0