aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/lockd/svc4proc.c6
-rw-r--r--fs/lockd/svcproc.c6
-rw-r--r--include/linux/lockd/lockd.h41
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
280static 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)
288static 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) */
295static 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 */
307static 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
280static inline int __nlm_cmp_addr4(const struct sockaddr *sap1, 321static inline int __nlm_cmp_addr4(const struct sockaddr *sap1,
281 const struct sockaddr *sap2) 322 const struct sockaddr *sap2)
282{ 323{