aboutsummaryrefslogtreecommitdiffstats
path: root/fs/lockd/mon.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/lockd/mon.c')
-rw-r--r--fs/lockd/mon.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 99aec744474c..8ae4c02d7dfd 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -9,6 +9,8 @@
9#include <linux/types.h> 9#include <linux/types.h>
10#include <linux/utsname.h> 10#include <linux/utsname.h>
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/ktime.h>
13
12#include <linux/sunrpc/clnt.h> 14#include <linux/sunrpc/clnt.h>
13#include <linux/sunrpc/xprtsock.h> 15#include <linux/sunrpc/xprtsock.h>
14#include <linux/sunrpc/svc.h> 16#include <linux/sunrpc/svc.h>
@@ -240,13 +242,25 @@ static struct nsm_handle *nsm_lookup_priv(const struct nsm_private *priv)
240 * returned via NLMPROC_SM_NOTIFY, in the "priv" field of these 242 * returned via NLMPROC_SM_NOTIFY, in the "priv" field of these
241 * requests. 243 * requests.
242 * 244 *
243 * Linux provides the raw IP address of the monitored host, 245 * The NSM protocol requires that these cookies be unique while the
244 * left in network byte order. 246 * system is running. We prefer a stronger requirement of making them
247 * unique across reboots. If user space bugs cause a stale cookie to
248 * be sent to the kernel, it could cause the wrong host to lose its
249 * lock state if cookies were not unique across reboots.
250 *
251 * The cookies are exposed only to local user space via loopback. They
252 * do not appear on the physical network. If we want greater security
253 * for some reason, nsm_init_private() could perform a one-way hash to
254 * obscure the contents of the cookie.
245 */ 255 */
246static void nsm_init_private(struct nsm_handle *nsm) 256static void nsm_init_private(struct nsm_handle *nsm)
247{ 257{
248 __be32 *p = (__be32 *)&nsm->sm_priv.data; 258 u64 *p = (u64 *)&nsm->sm_priv.data;
249 *p = nsm_addr_in(nsm)->sin_addr.s_addr; 259 struct timespec ts;
260
261 ktime_get_ts(&ts);
262 *p++ = timespec_to_ns(&ts);
263 *p = (unsigned long)nsm;
250} 264}
251 265
252static struct nsm_handle *nsm_create_handle(const struct sockaddr *sap, 266static struct nsm_handle *nsm_create_handle(const struct sockaddr *sap,
@@ -351,11 +365,7 @@ struct nsm_handle *nsm_reboot_lookup(const struct nlm_reboot *info)
351 365
352 spin_lock(&nsm_lock); 366 spin_lock(&nsm_lock);
353 367
354 if (nsm_use_hostnames && info->mon != NULL) 368 cached = nsm_lookup_priv(&info->priv);
355 cached = nsm_lookup_hostname(info->mon, info->len);
356 else
357 cached = nsm_lookup_priv(&info->priv);
358
359 if (unlikely(cached == NULL)) { 369 if (unlikely(cached == NULL)) {
360 spin_unlock(&nsm_lock); 370 spin_unlock(&nsm_lock);
361 dprintk("lockd: never saw rebooted peer '%.*s' before\n", 371 dprintk("lockd: never saw rebooted peer '%.*s' before\n",