diff options
Diffstat (limited to 'fs/lockd/mon.c')
-rw-r--r-- | fs/lockd/mon.c | 28 |
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 | */ |
246 | static void nsm_init_private(struct nsm_handle *nsm) | 256 | static 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 | ||
252 | static struct nsm_handle *nsm_create_handle(const struct sockaddr *sap, | 266 | static 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", |