All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 3.4 0/9] fix the NULL pointer when use nfs in diferent net ns
@ 2014-04-30  2:43   ` Weng Meiling
  2014-04-30  2:43     ` [PATCH v2 3.4 1/9] nfsd: pass net to nfsd_init_socks() Weng Meiling
                       ` (10 more replies)
  0 siblings, 11 replies; 13+ messages in thread
From: Weng Meiling @ 2014-04-30  2:43 UTC (permalink / raw)
  To: stable; +Cc: bfields, greg, lizefan, skinsbursky, h.huangqiang, linux-nfs

After 3.4 stable apply commit f7fb86c6e639(nfsd: use "init_net"
for portmapper). When starting NFSd in a non init_net network 
namespace will trigger kernel panic. Because RPCBIND client 
will be NULL when register RPC service with the local portmapper
in svc_addsock(). This new bug also exists in 3.8, but disappears
after patch commit 11f779421a39("containerize NFSd filesystem") in
3.9. 

So backport Stanislav's patches from 3.8 and 3.9 to cleanup init_net
reference, and get proper network namespace from superblock instead of 
using hard-coded "init_net" to make NFSd keep using a consistent network
namespace all the time to resolve the bug.

After this patchset, testing NFS in different network namespace will
not trigger kernel panic any more, and other NFS client can use the 
NFS server's shared files normally which was started in init_net namespace.

v1->v2:
- no commit 7fb86c6e639(nfsd: use "init_net" for portmapper) which has been
  apply to 3.4 stable in the first version
- one more fix patch commit 3064639423c4(nfsd: check passed socket's net matches
  NFSd superblock's one) for commit 11f779421a39("nfsd: containerize NFSd filesystem")
- fix build error for commit db6e182c17cb(nfsd: pass net to nfsd_init_socks())

Stanislav Kinsbursky (9):
  nfsd: pass net to nfsd_init_socks()
  nfsd: pass net to nfsd_startup() and nfsd_shutdown()
  nfsd: pass net to nfsd_create_serv()
  nfsd: pass net to nfsd_svc()
  nfsd: pass net to nfsd_set_nrthreads()
  nfsd: pass net to __write_ports() and down
  nfsd: pass proper net to nfsd_destroy() from NFSd kthreads
  nfsd: containerize NFSd filesystem
  nfsd: check passed socket's net matches NFSd superblock's one

 fs/nfsd/nfsctl.c               | 62 +++++++++++++++++++++++++++++-------------
 fs/nfsd/nfsd.h                 |  6 ++--
 fs/nfsd/nfssvc.c               | 41 ++++++++++++++--------------
 include/linux/sunrpc/svcsock.h |  1 +
 net/sunrpc/svcsock.c           | 16 +++++++++++
 5 files changed, 83 insertions(+), 43 deletions(-)

-- 
1.8.2.2



^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v2 3.4 1/9] nfsd: pass net to nfsd_init_socks()
  2014-04-30  2:43   ` [PATCH v2 3.4 0/9] fix the NULL pointer when use nfs in diferent net ns Weng Meiling
@ 2014-04-30  2:43     ` Weng Meiling
  2014-04-30  2:43     ` [PATCH v2 3.4 2/9] nfsd: pass net to nfsd_startup() and nfsd_shutdown() Weng Meiling
                       ` (9 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Weng Meiling @ 2014-04-30  2:43 UTC (permalink / raw)
  To: stable; +Cc: bfields, greg, lizefan, skinsbursky, h.huangqiang, linux-nfs

From: Stanislav Kinsbursky <skinsbursky@parallels.com>

commit db6e182c17cb1a7069f7f8924721ce58ac05d9a3 upstream.

Precursor patch. Hard-coded "init_net" will be replaced by proper one in
future.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
[wengmeiling: backport to 3.4:
 - adjust context
 - one more parameter(int port) for nfsd_init_socks()
 - net initialization in nfsd_startup()]
Signed-off-by: Weng Meiling <wengmeiling.weng@huawei.com>
---
 fs/nfsd/nfssvc.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 25d839e..517a883 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -182,18 +182,18 @@ int nfsd_nrthreads(void)
 	return rv;
 }
 
-static int nfsd_init_socks(int port)
+static int nfsd_init_socks(int port, struct net *net)
 {
 	int error;
 	if (!list_empty(&nfsd_serv->sv_permsocks))
 		return 0;
 
-	error = svc_create_xprt(nfsd_serv, "udp", &init_net, PF_INET, port,
+	error = svc_create_xprt(nfsd_serv, "udp", net, PF_INET, port,
 					SVC_SOCK_DEFAULTS);
 	if (error < 0)
 		return error;
 
-	error = svc_create_xprt(nfsd_serv, "tcp", &init_net, PF_INET, port,
+	error = svc_create_xprt(nfsd_serv, "tcp", net, PF_INET, port,
 					SVC_SOCK_DEFAULTS);
 	if (error < 0)
 		return error;
@@ -206,6 +206,7 @@ static bool nfsd_up = false;
 static int nfsd_startup(unsigned short port, int nrservs)
 {
 	int ret;
+	struct net *net = &init_net;
 
 	if (nfsd_up)
 		return 0;
@@ -217,7 +218,7 @@ static int nfsd_startup(unsigned short port, int nrservs)
 	ret = nfsd_racache_init(2*nrservs);
 	if (ret)
 		return ret;
-	ret = nfsd_init_socks(port);
+	ret = nfsd_init_socks(port, net);
 	if (ret)
 		goto out_racache;
 	ret = lockd_up(&init_net);
-- 
1.8.2.2



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2 3.4 2/9] nfsd: pass net to nfsd_startup() and nfsd_shutdown()
  2014-04-30  2:43   ` [PATCH v2 3.4 0/9] fix the NULL pointer when use nfs in diferent net ns Weng Meiling
  2014-04-30  2:43     ` [PATCH v2 3.4 1/9] nfsd: pass net to nfsd_init_socks() Weng Meiling
@ 2014-04-30  2:43     ` Weng Meiling
  2014-04-30  2:43     ` [PATCH v2 3.4 3/9] nfsd: pass net to nfsd_create_serv() Weng Meiling
                       ` (8 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Weng Meiling @ 2014-04-30  2:43 UTC (permalink / raw)
  To: stable; +Cc: bfields, greg, lizefan, skinsbursky, h.huangqiang, linux-nfs

From: Stanislav Kinsbursky <skinsbursky@parallels.com>

commit db42d1a76a8dfcaba7a2dc9c591fa4e231db22b3 upstream.

Precursor patch. Hard-coded "init_net" will be replaced by proper one in
future.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
[wengmeiling: backport to 3.4:
 - adjust context
 - one more parameter(int port) for nfsd_startup()
 - no net ns initialization in nfsd_shutdown()
 - pass @net to lockd_up() in nfsd_startup()
 - pass @net to lockd_down() in nfsd_shutdown()]
Signed-off-by: Weng Meiling <wengmeiling.weng@huawei.com>
---
 fs/nfsd/nfssvc.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 517a883..f8dae75 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -203,10 +203,9 @@ static int nfsd_init_socks(int port, struct net *net)
 
 static bool nfsd_up = false;
 
-static int nfsd_startup(unsigned short port, int nrservs)
+static int nfsd_startup(unsigned short port, int nrservs, struct net *net)
 {
 	int ret;
-	struct net *net = &init_net;
 
 	if (nfsd_up)
 		return 0;
@@ -221,7 +220,7 @@ static int nfsd_startup(unsigned short port, int nrservs)
 	ret = nfsd_init_socks(port, net);
 	if (ret)
 		goto out_racache;
-	ret = lockd_up(&init_net);
+	ret = lockd_up(net);
 	if (ret)
 		goto out_racache;
 	ret = nfs4_state_start();
@@ -230,13 +229,13 @@ static int nfsd_startup(unsigned short port, int nrservs)
 	nfsd_up = true;
 	return 0;
 out_lockd:
-	lockd_down(&init_net);
+	lockd_down(net);
 out_racache:
 	nfsd_racache_shutdown();
 	return ret;
 }
 
-static void nfsd_shutdown(void)
+static void nfsd_shutdown(struct net *net)
 {
 	/*
 	 * write_ports can create the server without actually starting
@@ -247,14 +246,14 @@ static void nfsd_shutdown(void)
 	if (!nfsd_up)
 		return;
 	nfs4_state_shutdown();
-	lockd_down(&init_net);
+	lockd_down(net);
 	nfsd_racache_shutdown();
 	nfsd_up = false;
 }
 
 static void nfsd_last_thread(struct svc_serv *serv, struct net *net)
 {
-	nfsd_shutdown();
+	nfsd_shutdown(net);
 
 	svc_rpcb_cleanup(serv, net);
 
@@ -458,7 +457,7 @@ nfsd_svc(unsigned short port, int nrservs)
 
 	nfsd_up_before = nfsd_up;
 
-	error = nfsd_startup(port, nrservs);
+	error = nfsd_startup(port, nrservs, net);
 	if (error)
 		goto out_destroy;
 	error = svc_set_num_threads(nfsd_serv, NULL, nrservs);
@@ -471,7 +470,7 @@ nfsd_svc(unsigned short port, int nrservs)
 	error = nfsd_serv->sv_nrthreads - 1;
 out_shutdown:
 	if (error < 0 && !nfsd_up_before)
-		nfsd_shutdown();
+		nfsd_shutdown(net);
 out_destroy:
 	nfsd_destroy(net);		/* Release server */
 out:
-- 
1.8.2.2



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2 3.4 3/9] nfsd: pass net to nfsd_create_serv()
  2014-04-30  2:43   ` [PATCH v2 3.4 0/9] fix the NULL pointer when use nfs in diferent net ns Weng Meiling
  2014-04-30  2:43     ` [PATCH v2 3.4 1/9] nfsd: pass net to nfsd_init_socks() Weng Meiling
  2014-04-30  2:43     ` [PATCH v2 3.4 2/9] nfsd: pass net to nfsd_startup() and nfsd_shutdown() Weng Meiling
@ 2014-04-30  2:43     ` Weng Meiling
  2014-04-30  2:43     ` [PATCH v2 3.4 4/9] nfsd: pass net to nfsd_svc() Weng Meiling
                       ` (7 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Weng Meiling @ 2014-04-30  2:43 UTC (permalink / raw)
  To: stable; +Cc: bfields, greg, lizefan, skinsbursky, h.huangqiang, linux-nfs

From: Stanislav Kinsbursky <skinsbursky@parallels.com>

commit 6777436b0f072fb20a025a73e9b67a35ad8a5451 upstream.

Precursor patch. Hard-coded "init_net" will be replaced by proper one in
future.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
[wengmeiling: backport to 3.4: adjust context]
Signed-off-by: Weng Meiling <wengmeiling.weng@huawei.com>
---
 fs/nfsd/nfsctl.c | 4 ++--
 fs/nfsd/nfsd.h   | 2 +-
 fs/nfsd/nfssvc.c | 5 ++---
 3 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index d014727..e18f0a5 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -657,7 +657,7 @@ static ssize_t __write_ports_addfd(char *buf)
 	if (err != 0 || fd < 0)
 		return -EINVAL;
 
-	err = nfsd_create_serv();
+	err = nfsd_create_serv(net);
 	if (err != 0)
 		return err;
 
@@ -708,7 +708,7 @@ static ssize_t __write_ports_addxprt(char *buf)
 	if (port < 1 || port > USHRT_MAX)
 		return -EINVAL;
 
-	err = nfsd_create_serv();
+	err = nfsd_create_serv(net);
 	if (err != 0)
 		return err;
 
diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
index 1336a65..356da43 100644
--- a/fs/nfsd/nfsd.h
+++ b/fs/nfsd/nfsd.h
@@ -101,7 +101,7 @@ enum vers_op {NFSD_SET, NFSD_CLEAR, NFSD_TEST, NFSD_AVAIL };
 int nfsd_vers(int vers, enum vers_op change);
 int nfsd_minorversion(u32 minorversion, enum vers_op change);
 void nfsd_reset_versions(void);
-int nfsd_create_serv(void);
+int nfsd_create_serv(struct net *net);
 
 extern int nfsd_max_blksize;
 
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index f8dae75..632d11e 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -326,10 +326,9 @@ static int nfsd_get_default_max_blksize(void)
 	return ret;
 }
 
-int nfsd_create_serv(void)
+int nfsd_create_serv(struct net *net)
 {
 	int error;
-	struct net *net = &init_net;
 
 	WARN_ON(!mutex_is_locked(&nfsd_mutex));
 	if (nfsd_serv) {
@@ -451,7 +450,7 @@ nfsd_svc(unsigned short port, int nrservs)
 	if (nrservs == 0 && nfsd_serv == NULL)
 		goto out;
 
-	error = nfsd_create_serv();
+	error = nfsd_create_serv(net);
 	if (error)
 		goto out;
 
-- 
1.8.2.2



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2 3.4 4/9] nfsd: pass net to nfsd_svc()
  2014-04-30  2:43   ` [PATCH v2 3.4 0/9] fix the NULL pointer when use nfs in diferent net ns Weng Meiling
                       ` (2 preceding siblings ...)
  2014-04-30  2:43     ` [PATCH v2 3.4 3/9] nfsd: pass net to nfsd_create_serv() Weng Meiling
@ 2014-04-30  2:43     ` Weng Meiling
  2014-04-30  2:43     ` [PATCH v2 3.4 5/9] nfsd: pass net to nfsd_set_nrthreads() Weng Meiling
                       ` (6 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Weng Meiling @ 2014-04-30  2:43 UTC (permalink / raw)
  To: stable; +Cc: bfields, greg, lizefan, skinsbursky, h.huangqiang, linux-nfs

From: Stanislav Kinsbursky <skinsbursky@parallels.com>

commit d41a9417cd89a69f58a26935034b4264a2d882d6 upstream.

Precursor patch. Hard-coded "init_net" will be replaced by proper one in
future.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
[wengmeiling: backport to 3.4:
 - adjust context
 - one more parameter(int port) for nfsd_svc()]
Signed-off-by: Weng Meiling <wengmeiling.weng@huawei.com>
---
 fs/nfsd/nfsctl.c | 4 +++-
 fs/nfsd/nfsd.h   | 2 +-
 fs/nfsd/nfssvc.c | 3 +--
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index e18f0a5..9463bc0 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -389,6 +389,8 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size)
 {
 	char *mesg = buf;
 	int rv;
+	struct net *net = &init_net;
+
 	if (size > 0) {
 		int newthreads;
 		rv = get_int(&mesg, &newthreads);
@@ -396,7 +398,7 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size)
 			return rv;
 		if (newthreads < 0)
 			return -EINVAL;
-		rv = nfsd_svc(NFS_PORT, newthreads);
+		rv = nfsd_svc(NFS_PORT, newthreads, net);
 		if (rv < 0)
 			return rv;
 	} else
diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
index 356da43..5007654 100644
--- a/fs/nfsd/nfsd.h
+++ b/fs/nfsd/nfsd.h
@@ -65,7 +65,7 @@ extern const struct seq_operations nfs_exports_op;
 /*
  * Function prototypes.
  */
-int		nfsd_svc(unsigned short port, int nrservs);
+int		nfsd_svc(unsigned short port, int nrservs, struct net *net);
 int		nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp);
 
 int		nfsd_nrthreads(void);
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 632d11e..b8aea64 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -434,11 +434,10 @@ int nfsd_set_nrthreads(int n, int *nthreads)
  * this is the first time nrservs is nonzero.
  */
 int
-nfsd_svc(unsigned short port, int nrservs)
+nfsd_svc(unsigned short port, int nrservs, struct net *net)
 {
 	int	error;
 	bool	nfsd_up_before;
-	struct net *net = &init_net;
 
 	mutex_lock(&nfsd_mutex);
 	dprintk("nfsd: creating service\n");
-- 
1.8.2.2



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2 3.4 5/9] nfsd: pass net to nfsd_set_nrthreads()
  2014-04-30  2:43   ` [PATCH v2 3.4 0/9] fix the NULL pointer when use nfs in diferent net ns Weng Meiling
                       ` (3 preceding siblings ...)
  2014-04-30  2:43     ` [PATCH v2 3.4 4/9] nfsd: pass net to nfsd_svc() Weng Meiling
@ 2014-04-30  2:43     ` Weng Meiling
  2014-04-30  2:43     ` [PATCH v2 3.4 6/9] nfsd: pass net to __write_ports() and down Weng Meiling
                       ` (5 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Weng Meiling @ 2014-04-30  2:43 UTC (permalink / raw)
  To: stable; +Cc: bfields, greg, lizefan, skinsbursky, h.huangqiang, linux-nfs

From: Stanislav Kinsbursky <skinsbursky@parallels.com>

commit 3938a0d5eb5effcc89c6909741403f4e6a37252d upstream.

Precursor patch. Hard-coded "init_net" will be replaced by proper one in
future.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
[wengmeiling: backport to 3.4: adjust context]
Signed-off-by: Weng Meiling <wengmeiling.weng@huawei.com>
---
 fs/nfsd/nfsctl.c | 3 ++-
 fs/nfsd/nfsd.h   | 2 +-
 fs/nfsd/nfssvc.c | 3 +--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 9463bc0..f58e0f9 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -440,6 +440,7 @@ static ssize_t write_pool_threads(struct file *file, char *buf, size_t size)
 	int len;
 	int npools;
 	int *nthreads;
+	struct net *net = &init_net;
 
 	mutex_lock(&nfsd_mutex);
 	npools = nfsd_nrpools();
@@ -470,7 +471,7 @@ static ssize_t write_pool_threads(struct file *file, char *buf, size_t size)
 			if (nthreads[i] < 0)
 				goto out_free;
 		}
-		rv = nfsd_set_nrthreads(i, nthreads);
+		rv = nfsd_set_nrthreads(i, nthreads, net);
 		if (rv)
 			goto out_free;
 	}
diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
index 5007654..a0989a2 100644
--- a/fs/nfsd/nfsd.h
+++ b/fs/nfsd/nfsd.h
@@ -71,7 +71,7 @@ int		nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp);
 int		nfsd_nrthreads(void);
 int		nfsd_nrpools(void);
 int		nfsd_get_nrthreads(int n, int *);
-int		nfsd_set_nrthreads(int n, int *);
+int		nfsd_set_nrthreads(int n, int *, struct net *);
 
 static inline void nfsd_destroy(struct net *net)
 {
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index b8aea64..0974818 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -374,12 +374,11 @@ int nfsd_get_nrthreads(int n, int *nthreads)
 	return 0;
 }
 
-int nfsd_set_nrthreads(int n, int *nthreads)
+int nfsd_set_nrthreads(int n, int *nthreads, struct net *net)
 {
 	int i = 0;
 	int tot = 0;
 	int err = 0;
-	struct net *net = &init_net;
 
 	WARN_ON(!mutex_is_locked(&nfsd_mutex));
 
-- 
1.8.2.2



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2 3.4 6/9] nfsd: pass net to __write_ports() and down
  2014-04-30  2:43   ` [PATCH v2 3.4 0/9] fix the NULL pointer when use nfs in diferent net ns Weng Meiling
                       ` (4 preceding siblings ...)
  2014-04-30  2:43     ` [PATCH v2 3.4 5/9] nfsd: pass net to nfsd_set_nrthreads() Weng Meiling
@ 2014-04-30  2:43     ` Weng Meiling
  2014-04-30  2:43     ` [PATCH v2 3.4 7/9] nfsd: pass proper net to nfsd_destroy() from NFSd kthreads Weng Meiling
                       ` (4 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Weng Meiling @ 2014-04-30  2:43 UTC (permalink / raw)
  To: stable; +Cc: bfields, greg, lizefan, skinsbursky, h.huangqiang, linux-nfs

From: Stanislav Kinsbursky <skinsbursky@parallels.com>

commit 081603520b25f7b35ef63a363376a17c36ef74ed upstream.

Precursor patch. Hard-coded "init_net" will be replaced by proper one in
future.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
[wengmeiling: backport to 3.4:
 - adjust context
 - add net_ns parameter to __write_ports_delxprt()]
Signed-off-by: Weng Meiling <wengmeiling.weng@huawei.com>
---
 fs/nfsd/nfsctl.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index f58e0f9..1d74af2 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -650,11 +650,10 @@ static ssize_t __write_ports_names(char *buf)
  * a socket of a supported family/protocol, and we use it as an
  * nfsd listener.
  */
-static ssize_t __write_ports_addfd(char *buf)
+static ssize_t __write_ports_addfd(char *buf, struct net *net)
 {
 	char *mesg = buf;
 	int fd, err;
-	struct net *net = &init_net;
 
 	err = get_int(&mesg, &fd);
 	if (err != 0 || fd < 0)
@@ -698,12 +697,11 @@ static ssize_t __write_ports_delfd(char *buf)
  * A transport listener is added by writing it's transport name and
  * a port number.
  */
-static ssize_t __write_ports_addxprt(char *buf)
+static ssize_t __write_ports_addxprt(char *buf, struct net *net)
 {
 	char transport[16];
 	struct svc_xprt *xprt;
 	int port, err;
-	struct net *net = &init_net;
 
 	if (sscanf(buf, "%15s %4u", transport, &port) != 2)
 		return -EINVAL;
@@ -743,7 +741,7 @@ out_err:
  * A transport listener is removed by writing a "-", it's transport
  * name, and it's port number.
  */
-static ssize_t __write_ports_delxprt(char *buf)
+static ssize_t __write_ports_delxprt(char *buf, struct net *net)
 {
 	struct svc_xprt *xprt;
 	char transport[16];
@@ -755,7 +753,7 @@ static ssize_t __write_ports_delxprt(char *buf)
 	if (port < 1 || port > USHRT_MAX || nfsd_serv == NULL)
 		return -EINVAL;
 
-	xprt = svc_find_xprt(nfsd_serv, transport, &init_net, AF_UNSPEC, port);
+	xprt = svc_find_xprt(nfsd_serv, transport, net, AF_UNSPEC, port);
 	if (xprt == NULL)
 		return -ENOTCONN;
 
@@ -764,22 +762,23 @@ static ssize_t __write_ports_delxprt(char *buf)
 	return 0;
 }
 
-static ssize_t __write_ports(struct file *file, char *buf, size_t size)
+static ssize_t __write_ports(struct file *file, char *buf, size_t size,
+				struct net *net)
 {
 	if (size == 0)
 		return __write_ports_names(buf);
 
 	if (isdigit(buf[0]))
-		return __write_ports_addfd(buf);
+		return __write_ports_addfd(buf, net);
 
 	if (buf[0] == '-' && isdigit(buf[1]))
 		return __write_ports_delfd(buf);
 
 	if (isalpha(buf[0]))
-		return __write_ports_addxprt(buf);
+		return __write_ports_addxprt(buf, net);
 
 	if (buf[0] == '-' && isalpha(buf[1]))
-		return __write_ports_delxprt(buf);
+		return __write_ports_delxprt(buf, net);
 
 	return -EINVAL;
 }
@@ -858,9 +857,10 @@ static ssize_t __write_ports(struct file *file, char *buf, size_t size)
 static ssize_t write_ports(struct file *file, char *buf, size_t size)
 {
 	ssize_t rv;
+	struct net *net = &init_net;
 
 	mutex_lock(&nfsd_mutex);
-	rv = __write_ports(file, buf, size);
+	rv = __write_ports(file, buf, size, net);
 	mutex_unlock(&nfsd_mutex);
 	return rv;
 }
-- 
1.8.2.2



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2 3.4 7/9] nfsd: pass proper net to nfsd_destroy() from NFSd kthreads
  2014-04-30  2:43   ` [PATCH v2 3.4 0/9] fix the NULL pointer when use nfs in diferent net ns Weng Meiling
                       ` (5 preceding siblings ...)
  2014-04-30  2:43     ` [PATCH v2 3.4 6/9] nfsd: pass net to __write_ports() and down Weng Meiling
@ 2014-04-30  2:43     ` Weng Meiling
  2014-04-30  2:43     ` [PATCH v2 3.4 8/9] nfsd: containerize NFSd filesystem Weng Meiling
                       ` (3 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Weng Meiling @ 2014-04-30  2:43 UTC (permalink / raw)
  To: stable; +Cc: bfields, greg, lizefan, skinsbursky, h.huangqiang, linux-nfs

From: Stanislav Kinsbursky <skinsbursky@parallels.com>

commit 88c47666171989ed4c5b1a5687df09511e8c5e35 upstream.

Since NFSd service is per-net now, we have to pass proper network
context in nfsd_shutdown() from NFSd kthreads.

The simplest way I found is to get proper net from one of transports
with permanent sockets.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
[wengmeiling: backport to 3.4: adjust context]
Signed-off-by: Weng Meiling <wengmeiling.weng@huawei.com>
---
 fs/nfsd/nfssvc.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 0974818..5bc9380 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -483,6 +483,8 @@ static int
 nfsd(void *vrqstp)
 {
 	struct svc_rqst *rqstp = (struct svc_rqst *) vrqstp;
+	struct svc_xprt *perm_sock = list_entry(rqstp->rq_server->sv_permsocks.next, typeof(struct svc_xprt), xpt_list);
+	struct net *net = perm_sock->xpt_net;
 	int err, preverr = 0;
 
 	/* Lock module and set up kernel thread */
@@ -557,7 +559,7 @@ out:
 	/* Release the thread */
 	svc_exit_thread(rqstp);
 
-	nfsd_destroy(&init_net);
+	nfsd_destroy(net);
 
 	/* Release module */
 	mutex_unlock(&nfsd_mutex);
-- 
1.8.2.2



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2 3.4 8/9] nfsd: containerize NFSd filesystem
  2014-04-30  2:43   ` [PATCH v2 3.4 0/9] fix the NULL pointer when use nfs in diferent net ns Weng Meiling
                       ` (6 preceding siblings ...)
  2014-04-30  2:43     ` [PATCH v2 3.4 7/9] nfsd: pass proper net to nfsd_destroy() from NFSd kthreads Weng Meiling
@ 2014-04-30  2:43     ` Weng Meiling
  2014-04-30  2:43     ` [PATCH v2 3.4 9/9] nfsd: check passed socket's net matches NFSd superblock's one Weng Meiling
                       ` (2 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Weng Meiling @ 2014-04-30  2:43 UTC (permalink / raw)
  To: stable; +Cc: bfields, greg, lizefan, skinsbursky, h.huangqiang, linux-nfs

From: Stanislav Kinsbursky <skinsbursky@parallels.com>

note: this backport is just for the null pointer problem when
start nfsd in none init netns. The nfsd is still not containerized.

commit 11f779421a39b86da8a523d97e5fd3477878d44f upstream.

This patch makes NFSD file system superblock to be created per net.
This makes possible to get proper network namespace from superblock instead of
using hard-coded "init_net".

Note: NFSd fs super-block holds network namespace. This garantees, that
network namespace won't disappear from underneath of it.
This, obviously, means, that in case of kill of a container's "init" (which is not a mount
namespace, but network namespace creator) netowrk namespace won't be
destroyed.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
[wengmeiling: backport to 3.4:
 - export cache not per netns
 - NFSD service structure not per netns]
Signed-off-by: Weng Meiling <wengmeiling.weng@huawei.com>
---
 fs/nfsd/nfsctl.c | 30 +++++++++++++++++++++++-------
 fs/nfsd/nfssvc.c |  2 +-
 2 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 1d74af2..cebc9ef 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -213,6 +213,7 @@ static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size)
 	struct sockaddr *sap = (struct sockaddr *)&address;
 	size_t salen = sizeof(address);
 	char *fo_path;
+	struct net *net = file->f_dentry->d_sb->s_fs_info;
 
 	/* sanity check */
 	if (size == 0)
@@ -225,7 +226,7 @@ static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size)
 	if (qword_get(&buf, fo_path, size) < 0)
 		return -EINVAL;
 
-	if (rpc_pton(&init_net, fo_path, size, sap, salen) == 0)
+	if (rpc_pton(net, fo_path, size, sap, salen) == 0)
 		return -EINVAL;
 
 	return nlmsvc_unlock_all_by_ip(sap);
@@ -389,7 +390,7 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size)
 {
 	char *mesg = buf;
 	int rv;
-	struct net *net = &init_net;
+	struct net *net = file->f_dentry->d_sb->s_fs_info;
 
 	if (size > 0) {
 		int newthreads;
@@ -440,7 +441,7 @@ static ssize_t write_pool_threads(struct file *file, char *buf, size_t size)
 	int len;
 	int npools;
 	int *nthreads;
-	struct net *net = &init_net;
+	struct net *net = file->f_dentry->d_sb->s_fs_info;
 
 	mutex_lock(&nfsd_mutex);
 	npools = nfsd_nrpools();
@@ -857,7 +858,7 @@ static ssize_t __write_ports(struct file *file, char *buf, size_t size,
 static ssize_t write_ports(struct file *file, char *buf, size_t size)
 {
 	ssize_t rv;
-	struct net *net = &init_net;
+	struct net *net = file->f_dentry->d_sb->s_fs_info;
 
 	mutex_lock(&nfsd_mutex);
 	rv = __write_ports(file, buf, size, net);
@@ -1095,20 +1096,35 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
 #endif
 		/* last one */ {""}
 	};
-	return simple_fill_super(sb, 0x6e667364, nfsd_files);
+	struct net *net = data;
+	int ret;
+
+	ret = simple_fill_super(sb, 0x6e667364, nfsd_files);
+	if (ret)
+		return ret;
+	sb->s_fs_info = get_net(net);
+	return 0;
 }
 
 static struct dentry *nfsd_mount(struct file_system_type *fs_type,
 	int flags, const char *dev_name, void *data)
 {
-	return mount_single(fs_type, flags, data, nfsd_fill_super);
+	return mount_ns(fs_type, flags, current->nsproxy->net_ns, nfsd_fill_super);
+}
+
+static void nfsd_umount(struct super_block *sb)
+{
+	struct net *net = sb->s_fs_info;
+
+	kill_litter_super(sb);
+	put_net(net);
 }
 
 static struct file_system_type nfsd_fs_type = {
 	.owner		= THIS_MODULE,
 	.name		= "nfsd",
 	.mount		= nfsd_mount,
-	.kill_sb	= kill_litter_super,
+	.kill_sb	= nfsd_umount,
 };
 
 #ifdef CONFIG_PROC_FS
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 5bc9380..ed8eedf 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -670,7 +670,7 @@ int nfsd_pool_stats_open(struct inode *inode, struct file *file)
 int nfsd_pool_stats_release(struct inode *inode, struct file *file)
 {
 	int ret = seq_release(inode, file);
-	struct net *net = &init_net;
+	struct net *net = inode->i_sb->s_fs_info;
 
 	mutex_lock(&nfsd_mutex);
 	/* this function really, really should have been called svc_put() */
-- 
1.8.2.2



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2 3.4 9/9] nfsd: check passed socket's net matches NFSd superblock's one
  2014-04-30  2:43   ` [PATCH v2 3.4 0/9] fix the NULL pointer when use nfs in diferent net ns Weng Meiling
                       ` (7 preceding siblings ...)
  2014-04-30  2:43     ` [PATCH v2 3.4 8/9] nfsd: containerize NFSd filesystem Weng Meiling
@ 2014-04-30  2:43     ` Weng Meiling
  2014-05-04 12:30     ` [PATCH v2 3.4 0/9] fix the NULL pointer when use nfs in diferent net ns J. Bruce Fields
       [not found]     ` <1398841733-10144-1-git-send-email-rui.xiang@huawei.com>
  10 siblings, 0 replies; 13+ messages in thread
From: Weng Meiling @ 2014-04-30  2:43 UTC (permalink / raw)
  To: stable; +Cc: bfields, greg, lizefan, skinsbursky, h.huangqiang, linux-nfs

From: Stanislav Kinsbursky <skinsbursky@parallels.com>

commit 3064639423c48d6e0eb9ecc27c512a58e38c6c57 upstream.

There could be a case, when NFSd file system is mounted in network, different
to socket's one, like below:

"ip netns exec" creates new network and mount namespace, which duplicates NFSd
mount point, created in init_net context. And thus NFS server stop in nested
network context leads to RPCBIND client destruction in init_net.
Then, on NFSd start in nested network context, rpc.nfsd process creates socket
in nested net and passes it into "write_ports", which leads to RPCBIND sockets
creation in init_net context because of the same reason (NFSd monut point was
created in init_net context). An attempt to register passed socket in nested
net leads to panic, because no RPCBIND client present in nexted network
namespace.

This patch add check that passed socket's net matches NFSd superblock's one.
And returns -EINVAL error to user psace otherwise.

v2: Put socket on exit.

Reported-by: Weng Meiling <wengmeiling.weng@huawei.com>
Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
Cc: stable@vger.kernel.org
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
[wengmeiling: backport to 3.4: adjust context]
Signed-off-by: Weng Meiling <wengmeiling.weng@huawei.com>
---
 fs/nfsd/nfsctl.c               |  5 +++++
 include/linux/sunrpc/svcsock.h |  1 +
 net/sunrpc/svcsock.c           | 16 ++++++++++++++++
 3 files changed, 22 insertions(+)

diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index cebc9ef..4db777d 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -660,6 +660,11 @@ static ssize_t __write_ports_addfd(char *buf, struct net *net)
 	if (err != 0 || fd < 0)
 		return -EINVAL;
 
+	if (svc_alien_sock(net, fd)) {
+		printk(KERN_ERR "%s: socket net is different to NFSd's one\n", __func__);
+		return -EINVAL;
+	}
+
 	err = nfsd_create_serv(net);
 	if (err != 0)
 		return err;
diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h
index cb4ac69..e4c6cec 100644
--- a/include/linux/sunrpc/svcsock.h
+++ b/include/linux/sunrpc/svcsock.h
@@ -42,6 +42,7 @@ void		svc_sock_update_bufs(struct svc_serv *serv);
 int		svc_sock_names(struct svc_serv *serv, char *buf,
 					const size_t buflen,
 					const char *toclose);
+bool		svc_alien_sock(struct net *net, int fd);
 int		svc_addsock(struct svc_serv *serv, const int fd,
 					char *name_return, const size_t len);
 void		svc_init_xprt_sock(void);
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index f190ea9..4c23cfc 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -1441,6 +1441,22 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
 	return svsk;
 }
 
+bool svc_alien_sock(struct net *net, int fd)
+{
+	int err;
+	struct socket *sock = sockfd_lookup(fd, &err);
+	bool ret = false;
+
+	if (!sock)
+		goto out;
+	if (sock_net(sock->sk) != net)
+		ret = true;
+	sockfd_put(sock);
+out:
+	return ret;
+}
+EXPORT_SYMBOL_GPL(svc_alien_sock);
+
 /**
  * svc_addsock - add a listener socket to an RPC service
  * @serv: pointer to RPC service to which to add a new listener
-- 
1.8.2.2



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 3.4 0/9] fix the NULL pointer when use nfs in diferent net ns
  2014-04-30  2:43   ` [PATCH v2 3.4 0/9] fix the NULL pointer when use nfs in diferent net ns Weng Meiling
                       ` (8 preceding siblings ...)
  2014-04-30  2:43     ` [PATCH v2 3.4 9/9] nfsd: check passed socket's net matches NFSd superblock's one Weng Meiling
@ 2014-05-04 12:30     ` J. Bruce Fields
  2014-06-09 23:49       ` Greg KH
       [not found]     ` <1398841733-10144-1-git-send-email-rui.xiang@huawei.com>
  10 siblings, 1 reply; 13+ messages in thread
From: J. Bruce Fields @ 2014-05-04 12:30 UTC (permalink / raw)
  To: Weng Meiling; +Cc: stable, greg, lizefan, skinsbursky, h.huangqiang, linux-nfs

ACK to these for stable.--b.

On Wed, Apr 30, 2014 at 10:43:35AM +0800, Weng Meiling wrote:
> After 3.4 stable apply commit f7fb86c6e639(nfsd: use "init_net"
> for portmapper). When starting NFSd in a non init_net network 
> namespace will trigger kernel panic. Because RPCBIND client 
> will be NULL when register RPC service with the local portmapper
> in svc_addsock(). This new bug also exists in 3.8, but disappears
> after patch commit 11f779421a39("containerize NFSd filesystem") in
> 3.9. 
> 
> So backport Stanislav's patches from 3.8 and 3.9 to cleanup init_net
> reference, and get proper network namespace from superblock instead of 
> using hard-coded "init_net" to make NFSd keep using a consistent network
> namespace all the time to resolve the bug.
> 
> After this patchset, testing NFS in different network namespace will
> not trigger kernel panic any more, and other NFS client can use the 
> NFS server's shared files normally which was started in init_net namespace.
> 
> v1->v2:
> - no commit 7fb86c6e639(nfsd: use "init_net" for portmapper) which has been
>   apply to 3.4 stable in the first version
> - one more fix patch commit 3064639423c4(nfsd: check passed socket's net matches
>   NFSd superblock's one) for commit 11f779421a39("nfsd: containerize NFSd filesystem")
> - fix build error for commit db6e182c17cb(nfsd: pass net to nfsd_init_socks())
> 
> Stanislav Kinsbursky (9):
>   nfsd: pass net to nfsd_init_socks()
>   nfsd: pass net to nfsd_startup() and nfsd_shutdown()
>   nfsd: pass net to nfsd_create_serv()
>   nfsd: pass net to nfsd_svc()
>   nfsd: pass net to nfsd_set_nrthreads()
>   nfsd: pass net to __write_ports() and down
>   nfsd: pass proper net to nfsd_destroy() from NFSd kthreads
>   nfsd: containerize NFSd filesystem
>   nfsd: check passed socket's net matches NFSd superblock's one
> 
>  fs/nfsd/nfsctl.c               | 62 +++++++++++++++++++++++++++++-------------
>  fs/nfsd/nfsd.h                 |  6 ++--
>  fs/nfsd/nfssvc.c               | 41 ++++++++++++++--------------
>  include/linux/sunrpc/svcsock.h |  1 +
>  net/sunrpc/svcsock.c           | 16 +++++++++++
>  5 files changed, 83 insertions(+), 43 deletions(-)
> 
> -- 
> 1.8.2.2
> 
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* pending 3.4.x backported patches.
       [not found]     ` <1398841733-10144-1-git-send-email-rui.xiang@huawei.com>
@ 2014-06-05  4:15       ` Greg KH
  0 siblings, 0 replies; 13+ messages in thread
From: Greg KH @ 2014-06-05  4:15 UTC (permalink / raw)
  To: Rui Xiang, Weng Meiling, Yijing Wang, Jianguo Wu
  Cc: stable, Ben Hutchings, Li Zefan, bfields, skinsbursky,
	h.huangqiang, linux-nfs

Hi all,

I've gotten through a lot of your 3.4 patches that you have backported,
or told me how to backport, thank you very much.

But, there are still more for me to do, and this kernel is big enough
for me to want to release it as-is.  So I'm going to hold off on the
rest of your pending patches for the next 3.4.x kernel release.

Don't worry, they aren't lost, and will get applied soon.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 3.4 0/9] fix the NULL pointer when use nfs in diferent net ns
  2014-05-04 12:30     ` [PATCH v2 3.4 0/9] fix the NULL pointer when use nfs in diferent net ns J. Bruce Fields
@ 2014-06-09 23:49       ` Greg KH
  0 siblings, 0 replies; 13+ messages in thread
From: Greg KH @ 2014-06-09 23:49 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: Weng Meiling, stable, lizefan, skinsbursky, h.huangqiang, linux-nfs

On Sun, May 04, 2014 at 08:30:11AM -0400, J. Bruce Fields wrote:
> ACK to these for stable.--b.

All now queued up, thanks.

greg k-h

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2014-06-09 23:45 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <5359B8F0.8030201@huawei.com>
     [not found] ` <1398409948-10180-1-git-send-email-wangyijing@huawei.com>
2014-04-30  2:43   ` [PATCH v2 3.4 0/9] fix the NULL pointer when use nfs in diferent net ns Weng Meiling
2014-04-30  2:43     ` [PATCH v2 3.4 1/9] nfsd: pass net to nfsd_init_socks() Weng Meiling
2014-04-30  2:43     ` [PATCH v2 3.4 2/9] nfsd: pass net to nfsd_startup() and nfsd_shutdown() Weng Meiling
2014-04-30  2:43     ` [PATCH v2 3.4 3/9] nfsd: pass net to nfsd_create_serv() Weng Meiling
2014-04-30  2:43     ` [PATCH v2 3.4 4/9] nfsd: pass net to nfsd_svc() Weng Meiling
2014-04-30  2:43     ` [PATCH v2 3.4 5/9] nfsd: pass net to nfsd_set_nrthreads() Weng Meiling
2014-04-30  2:43     ` [PATCH v2 3.4 6/9] nfsd: pass net to __write_ports() and down Weng Meiling
2014-04-30  2:43     ` [PATCH v2 3.4 7/9] nfsd: pass proper net to nfsd_destroy() from NFSd kthreads Weng Meiling
2014-04-30  2:43     ` [PATCH v2 3.4 8/9] nfsd: containerize NFSd filesystem Weng Meiling
2014-04-30  2:43     ` [PATCH v2 3.4 9/9] nfsd: check passed socket's net matches NFSd superblock's one Weng Meiling
2014-05-04 12:30     ` [PATCH v2 3.4 0/9] fix the NULL pointer when use nfs in diferent net ns J. Bruce Fields
2014-06-09 23:49       ` Greg KH
     [not found]     ` <1398841733-10144-1-git-send-email-rui.xiang@huawei.com>
2014-06-05  4:15       ` pending 3.4.x backported patches Greg KH

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.