diff options
-rw-r--r-- | fs/lockd/svc4proc.c | 6 | ||||
-rw-r--r-- | fs/lockd/svcproc.c | 6 | ||||
-rw-r--r-- | include/linux/lockd/lockd.h | 41 |
3 files changed, 45 insertions, 8 deletions
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index 50ee8eb139ab..014f6ce48172 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c | |||
@@ -421,11 +421,9 @@ nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, | |||
421 | { | 421 | { |
422 | struct sockaddr_in saddr; | 422 | struct sockaddr_in saddr; |
423 | 423 | ||
424 | memcpy(&saddr, svc_addr_in(rqstp), sizeof(saddr)); | ||
425 | |||
426 | dprintk("lockd: SM_NOTIFY called\n"); | 424 | dprintk("lockd: SM_NOTIFY called\n"); |
427 | if (saddr.sin_addr.s_addr != htonl(INADDR_LOOPBACK) | 425 | |
428 | || ntohs(saddr.sin_port) >= 1024) { | 426 | if (!nlm_privileged_requester(rqstp)) { |
429 | char buf[RPC_MAX_ADDRBUFLEN]; | 427 | char buf[RPC_MAX_ADDRBUFLEN]; |
430 | printk(KERN_WARNING "lockd: rejected NSM callback from %s\n", | 428 | printk(KERN_WARNING "lockd: rejected NSM callback from %s\n", |
431 | svc_print_addr(rqstp, buf, sizeof(buf))); | 429 | svc_print_addr(rqstp, buf, sizeof(buf))); |
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 935ce967a6a1..548b0bb2b84d 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c | |||
@@ -453,11 +453,9 @@ nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, | |||
453 | { | 453 | { |
454 | struct sockaddr_in saddr; | 454 | struct sockaddr_in saddr; |
455 | 455 | ||
456 | memcpy(&saddr, svc_addr_in(rqstp), sizeof(saddr)); | ||
457 | |||
458 | dprintk("lockd: SM_NOTIFY called\n"); | 456 | dprintk("lockd: SM_NOTIFY called\n"); |
459 | if (saddr.sin_addr.s_addr != htonl(INADDR_LOOPBACK) | 457 | |
460 | || ntohs(saddr.sin_port) >= 1024) { | 458 | if (!nlm_privileged_requester(rqstp)) { |
461 | char buf[RPC_MAX_ADDRBUFLEN]; | 459 | char buf[RPC_MAX_ADDRBUFLEN]; |
462 | printk(KERN_WARNING "lockd: rejected NSM callback from %s\n", | 460 | printk(KERN_WARNING "lockd: rejected NSM callback from %s\n", |
463 | svc_print_addr(rqstp, buf, sizeof(buf))); | 461 | svc_print_addr(rqstp, buf, sizeof(buf))); |
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index e6b070979287..b56d5aa9b194 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h | |||
@@ -277,6 +277,47 @@ static inline struct inode *nlmsvc_file_inode(struct nlm_file *file) | |||
277 | return file->f_file->f_path.dentry->d_inode; | 277 | return file->f_file->f_path.dentry->d_inode; |
278 | } | 278 | } |
279 | 279 | ||
280 | static inline int __nlm_privileged_request4(const struct sockaddr *sap) | ||
281 | { | ||
282 | const struct sockaddr_in *sin = (struct sockaddr_in *)sap; | ||
283 | return (sin->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) && | ||
284 | (ntohs(sin->sin_port) < 1024); | ||
285 | } | ||
286 | |||
287 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
288 | static inline int __nlm_privileged_request6(const struct sockaddr *sap) | ||
289 | { | ||
290 | const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap; | ||
291 | return (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LOOPBACK) && | ||
292 | (ntohs(sin6->sin6_port) < 1024); | ||
293 | } | ||
294 | #else /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ | ||
295 | static inline int __nlm_privileged_request6(const struct sockaddr *sap) | ||
296 | { | ||
297 | return 0; | ||
298 | } | ||
299 | #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ | ||
300 | |||
301 | /* | ||
302 | * Ensure incoming requests are from local privileged callers. | ||
303 | * | ||
304 | * Return TRUE if sender is local and is connecting via a privileged port; | ||
305 | * otherwise return FALSE. | ||
306 | */ | ||
307 | static inline int nlm_privileged_requester(const struct svc_rqst *rqstp) | ||
308 | { | ||
309 | const struct sockaddr *sap = svc_addr(rqstp); | ||
310 | |||
311 | switch (sap->sa_family) { | ||
312 | case AF_INET: | ||
313 | return __nlm_privileged_request4(sap); | ||
314 | case AF_INET6: | ||
315 | return __nlm_privileged_request6(sap); | ||
316 | default: | ||
317 | return 0; | ||
318 | } | ||
319 | } | ||
320 | |||
280 | static inline int __nlm_cmp_addr4(const struct sockaddr *sap1, | 321 | static inline int __nlm_cmp_addr4(const struct sockaddr *sap1, |
281 | const struct sockaddr *sap2) | 322 | const struct sockaddr *sap2) |
282 | { | 323 | { |