diff options
| author | Andrey Ryabinin <aryabinin@virtuozzo.com> | 2015-09-23 08:49:29 -0400 |
|---|---|---|
| committer | J. Bruce Fields <bfields@redhat.com> | 2015-10-12 17:31:05 -0400 |
| commit | 0ad95472bf169a3501991f8f33f5147f792a8116 (patch) | |
| tree | 3c2303ba0350c2dcd54db07c9883954ed9092c49 /include/linux/lockd | |
| parent | aaf91ec148910e0c2bfd135ea19f870e7196e64f (diff) | |
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 'include/linux/lockd')
| -rw-r--r-- | include/linux/lockd/lockd.h | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index ff82a32871b5..fd3b65bf51b5 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h | |||
| @@ -235,7 +235,8 @@ void nlm_rebind_host(struct nlm_host *); | |||
| 235 | struct nlm_host * nlm_get_host(struct nlm_host *); | 235 | struct nlm_host * nlm_get_host(struct nlm_host *); |
| 236 | void nlm_shutdown_hosts(void); | 236 | void nlm_shutdown_hosts(void); |
| 237 | void nlm_shutdown_hosts_net(struct net *net); | 237 | void nlm_shutdown_hosts_net(struct net *net); |
| 238 | void nlm_host_rebooted(const struct nlm_reboot *); | 238 | void nlm_host_rebooted(const struct net *net, |
| 239 | const struct nlm_reboot *); | ||
| 239 | 240 | ||
| 240 | /* | 241 | /* |
| 241 | * Host monitoring | 242 | * Host monitoring |
| @@ -243,11 +244,13 @@ void nlm_host_rebooted(const struct nlm_reboot *); | |||
| 243 | int nsm_monitor(const struct nlm_host *host); | 244 | int nsm_monitor(const struct nlm_host *host); |
| 244 | void nsm_unmonitor(const struct nlm_host *host); | 245 | void nsm_unmonitor(const struct nlm_host *host); |
| 245 | 246 | ||
| 246 | struct nsm_handle *nsm_get_handle(const struct sockaddr *sap, | 247 | struct nsm_handle *nsm_get_handle(const struct net *net, |
| 248 | const struct sockaddr *sap, | ||
| 247 | const size_t salen, | 249 | const size_t salen, |
| 248 | const char *hostname, | 250 | const char *hostname, |
| 249 | const size_t hostname_len); | 251 | const size_t hostname_len); |
| 250 | struct nsm_handle *nsm_reboot_lookup(const struct nlm_reboot *info); | 252 | struct nsm_handle *nsm_reboot_lookup(const struct net *net, |
| 253 | const struct nlm_reboot *info); | ||
| 251 | void nsm_release(struct nsm_handle *nsm); | 254 | void nsm_release(struct nsm_handle *nsm); |
| 252 | 255 | ||
| 253 | /* | 256 | /* |
