forked from mirrors/linux
		
	SUNRPC: lock against ->sock changing during sysfs read
->sock can be set to NULL asynchronously unless ->recv_mutex is held. So it is important to hold that mutex. Otherwise a sysfs read can trigger an oops. Commit17f09d3f61("SUNRPC: Check if the xprt is connected before handling sysfs reads") appears to attempt to fix this problem, but it only narrows the race window. Fixes:17f09d3f61("SUNRPC: Check if the xprt is connected before handling sysfs reads") Fixes:a8482488a7("SUNRPC query transport's source port") Signed-off-by: NeilBrown <neilb@suse.de> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
		
							parent
							
								
									63db37e99a
								
							
						
					
					
						commit
						b49ea673e1
					
				
					 2 changed files with 10 additions and 2 deletions
				
			
		| 
						 | 
					@ -115,11 +115,14 @@ static ssize_t rpc_sysfs_xprt_srcaddr_show(struct kobject *kobj,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sock = container_of(xprt, struct sock_xprt, xprt);
 | 
						sock = container_of(xprt, struct sock_xprt, xprt);
 | 
				
			||||||
	if (kernel_getsockname(sock->sock, (struct sockaddr *)&saddr) < 0)
 | 
						mutex_lock(&sock->recv_mutex);
 | 
				
			||||||
 | 
						if (sock->sock == NULL ||
 | 
				
			||||||
 | 
						    kernel_getsockname(sock->sock, (struct sockaddr *)&saddr) < 0)
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = sprintf(buf, "%pISc\n", &saddr);
 | 
						ret = sprintf(buf, "%pISc\n", &saddr);
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
 | 
						mutex_unlock(&sock->recv_mutex);
 | 
				
			||||||
	xprt_put(xprt);
 | 
						xprt_put(xprt);
 | 
				
			||||||
	return ret + 1;
 | 
						return ret + 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1641,7 +1641,12 @@ static int xs_get_srcport(struct sock_xprt *transport)
 | 
				
			||||||
unsigned short get_srcport(struct rpc_xprt *xprt)
 | 
					unsigned short get_srcport(struct rpc_xprt *xprt)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sock_xprt *sock = container_of(xprt, struct sock_xprt, xprt);
 | 
						struct sock_xprt *sock = container_of(xprt, struct sock_xprt, xprt);
 | 
				
			||||||
	return xs_sock_getport(sock->sock);
 | 
						unsigned short ret = 0;
 | 
				
			||||||
 | 
						mutex_lock(&sock->recv_mutex);
 | 
				
			||||||
 | 
						if (sock->sock)
 | 
				
			||||||
 | 
							ret = xs_sock_getport(sock->sock);
 | 
				
			||||||
 | 
						mutex_unlock(&sock->recv_mutex);
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(get_srcport);
 | 
					EXPORT_SYMBOL(get_srcport);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue