summary refs log tree commit diff
path: root/fs/lockd/svc.c
diff options
context:
space:
mode:
authorAndrey Ryabinin <aryabinin@virtuozzo.com>2015-09-23 15:49:29 +0300
committerJ. Bruce Fields <bfields@redhat.com>2015-10-12 17:31:05 -0400
commit0ad95472bf169a3501991f8f33f5147f792a8116 (patch)
tree3c2303ba0350c2dcd54db07c9883954ed9092c49 /fs/lockd/svc.c
parentaaf91ec148910e0c2bfd135ea19f870e7196e64f (diff)
downloadlinux-0ad95472bf169a3501991f8f33f5147f792a8116.tar.gz
lockd: create NSM handles per net namespace
Commit cb7323fffa85 ("lockd: create and use per-net NSM
 RPC clients on MON/UNMON requests") introduced per-net
NSM RPC clients. Unfortunately this doesn't make any sense
without per-net nsm_handle.

E.g. the following scenario could happen
Two hosts (X and Y) in different namespaces (A and B) share
the same nsm struct.

1. nsm_monitor(host_X) called => NSM rpc client created,
	nsm->sm_monitored bit set.
2. nsm_mointor(host-Y) called => nsm->sm_monitored already set,
	we just exit. Thus in namespace B ln->nsm_clnt == NULL.
3. host X destroyed => nsm->sm_count decremented to 1
4. host Y destroyed => nsm_unmonitor() => nsm_mon_unmon() => NULL-ptr
	dereference of *ln->nsm_clnt

So this could be fixed by making per-net nsm_handles list,
instead of global. Thus different net namespaces will not be able
share the same nsm_handle.

Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/lockd/svc.c')
-rw-r--r--fs/lockd/svc.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index d678bcc3cbcb..0dff13f41808 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -593,6 +593,7 @@ static int lockd_init_net(struct net *net)
 	INIT_LIST_HEAD(&ln->lockd_manager.list);
 	ln->lockd_manager.block_opens = false;
 	spin_lock_init(&ln->nsm_clnt_lock);
+	INIT_LIST_HEAD(&ln->nsm_handles);
 	return 0;
 }