mirror of https://gitee.com/openkylin/linux.git
lockd: Add helper to sanity check incoming NOTIFY requests
lockd accepts SM_NOTIFY calls only from a privileged process on the local system. If lockd uses an AF_INET6 listener, the sender's address (ie the local rpc.statd) will be the IPv6 loopback address, not the IPv4 loopback address. Make sure the privilege test in nlmsvc_proc_sm_notify() and nlm4svc_proc_sm_notify() works for both AF_INET and AF_INET6 family addresses by refactoring the test into a helper and adding support for IPv6 addresses. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
This commit is contained in:
parent
dcff09f124
commit
b85e467634
|
@ -421,11 +421,9 @@ nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
|
||||||
{
|
{
|
||||||
struct sockaddr_in saddr;
|
struct sockaddr_in saddr;
|
||||||
|
|
||||||
memcpy(&saddr, svc_addr_in(rqstp), sizeof(saddr));
|
|
||||||
|
|
||||||
dprintk("lockd: SM_NOTIFY called\n");
|
dprintk("lockd: SM_NOTIFY called\n");
|
||||||
if (saddr.sin_addr.s_addr != htonl(INADDR_LOOPBACK)
|
|
||||||
|| ntohs(saddr.sin_port) >= 1024) {
|
if (!nlm_privileged_requester(rqstp)) {
|
||||||
char buf[RPC_MAX_ADDRBUFLEN];
|
char buf[RPC_MAX_ADDRBUFLEN];
|
||||||
printk(KERN_WARNING "lockd: rejected NSM callback from %s\n",
|
printk(KERN_WARNING "lockd: rejected NSM callback from %s\n",
|
||||||
svc_print_addr(rqstp, buf, sizeof(buf)));
|
svc_print_addr(rqstp, buf, sizeof(buf)));
|
||||||
|
|
|
@ -453,11 +453,9 @@ nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
|
||||||
{
|
{
|
||||||
struct sockaddr_in saddr;
|
struct sockaddr_in saddr;
|
||||||
|
|
||||||
memcpy(&saddr, svc_addr_in(rqstp), sizeof(saddr));
|
|
||||||
|
|
||||||
dprintk("lockd: SM_NOTIFY called\n");
|
dprintk("lockd: SM_NOTIFY called\n");
|
||||||
if (saddr.sin_addr.s_addr != htonl(INADDR_LOOPBACK)
|
|
||||||
|| ntohs(saddr.sin_port) >= 1024) {
|
if (!nlm_privileged_requester(rqstp)) {
|
||||||
char buf[RPC_MAX_ADDRBUFLEN];
|
char buf[RPC_MAX_ADDRBUFLEN];
|
||||||
printk(KERN_WARNING "lockd: rejected NSM callback from %s\n",
|
printk(KERN_WARNING "lockd: rejected NSM callback from %s\n",
|
||||||
svc_print_addr(rqstp, buf, sizeof(buf)));
|
svc_print_addr(rqstp, buf, sizeof(buf)));
|
||||||
|
|
|
@ -277,6 +277,47 @@ static inline struct inode *nlmsvc_file_inode(struct nlm_file *file)
|
||||||
return file->f_file->f_path.dentry->d_inode;
|
return file->f_file->f_path.dentry->d_inode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int __nlm_privileged_request4(const struct sockaddr *sap)
|
||||||
|
{
|
||||||
|
const struct sockaddr_in *sin = (struct sockaddr_in *)sap;
|
||||||
|
return (sin->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) &&
|
||||||
|
(ntohs(sin->sin_port) < 1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||||
|
static inline int __nlm_privileged_request6(const struct sockaddr *sap)
|
||||||
|
{
|
||||||
|
const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
|
||||||
|
return (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LOOPBACK) &&
|
||||||
|
(ntohs(sin6->sin6_port) < 1024);
|
||||||
|
}
|
||||||
|
#else /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
|
||||||
|
static inline int __nlm_privileged_request6(const struct sockaddr *sap)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensure incoming requests are from local privileged callers.
|
||||||
|
*
|
||||||
|
* Return TRUE if sender is local and is connecting via a privileged port;
|
||||||
|
* otherwise return FALSE.
|
||||||
|
*/
|
||||||
|
static inline int nlm_privileged_requester(const struct svc_rqst *rqstp)
|
||||||
|
{
|
||||||
|
const struct sockaddr *sap = svc_addr(rqstp);
|
||||||
|
|
||||||
|
switch (sap->sa_family) {
|
||||||
|
case AF_INET:
|
||||||
|
return __nlm_privileged_request4(sap);
|
||||||
|
case AF_INET6:
|
||||||
|
return __nlm_privileged_request6(sap);
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline int __nlm_cmp_addr4(const struct sockaddr *sap1,
|
static inline int __nlm_cmp_addr4(const struct sockaddr *sap1,
|
||||||
const struct sockaddr *sap2)
|
const struct sockaddr *sap2)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue