Re: Patch "SUNRPC: NULL utsname dereference on NFS umount during namespace cleanup" has been added to the 3.14-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, Feb 28, 2015 at 03:06:04PM -0800, Greg Kroah-Hartman wrote:
> 
> This is a note to let you know that I've just added the patch titled
> 
>     SUNRPC: NULL utsname dereference on NFS umount during namespace cleanup
> 
> to the 3.14-stable tree which can be found at:
>     http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
> 
> The filename of the patch is:
>      sunrpc-null-utsname-dereference-on-nfs-umount-during-namespace-cleanup.patch
> and it can be found in the queue-3.14 subdirectory.
> 
> If you, or anyone else, feels it should not be added to the stable tree,
> please let <stable@xxxxxxxxxxxxxxx> know about it.
>

Maybe this is actually applicable to the 3.14 kernel, but it was
tagged for stable 3.18.  Trond?  Bruno?

Cheers,
--
Luís

> 
> From 03a9a42a1a7e5b3e7919ddfacc1d1cc81882a955 Mon Sep 17 00:00:00 2001
> From: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx>
> Date: Fri, 30 Jan 2015 18:12:28 -0500
> Subject: SUNRPC: NULL utsname dereference on NFS umount during namespace cleanup
> MIME-Version: 1.0
> Content-Type: text/plain; charset=UTF-8
> Content-Transfer-Encoding: 8bit
> 
> From: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx>
> 
> commit 03a9a42a1a7e5b3e7919ddfacc1d1cc81882a955 upstream.
> 
> Fix an Oopsable condition when nsm_mon_unmon is called as part of the
> namespace cleanup, which now apparently happens after the utsname
> has been freed.
> 
> Link: http://lkml.kernel.org/r/20150125220604.090121ae@xxxxxxxxxxxx
> Reported-by: Bruno Prémont <bonbons@xxxxxxxxxxxxxxxxx>
> Signed-off-by: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx>
> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
> 
> ---
>  fs/lockd/mon.c              |   13 +++++++++----
>  include/linux/sunrpc/clnt.h |    3 ++-
>  net/sunrpc/clnt.c           |   12 +++++++-----
>  net/sunrpc/rpcb_clnt.c      |    8 ++++++--
>  4 files changed, 24 insertions(+), 12 deletions(-)
> 
> --- a/fs/lockd/mon.c
> +++ b/fs/lockd/mon.c
> @@ -65,7 +65,7 @@ static inline struct sockaddr *nsm_addr(
>  	return (struct sockaddr *)&nsm->sm_addr;
>  }
>  
> -static struct rpc_clnt *nsm_create(struct net *net)
> +static struct rpc_clnt *nsm_create(struct net *net, const char *nodename)
>  {
>  	struct sockaddr_in sin = {
>  		.sin_family		= AF_INET,
> @@ -77,6 +77,7 @@ static struct rpc_clnt *nsm_create(struc
>  		.address		= (struct sockaddr *)&sin,
>  		.addrsize		= sizeof(sin),
>  		.servername		= "rpc.statd",
> +		.nodename		= nodename,
>  		.program		= &nsm_program,
>  		.version		= NSM_VERSION,
>  		.authflavor		= RPC_AUTH_NULL,
> @@ -102,7 +103,7 @@ out:
>  	return clnt;
>  }
>  
> -static struct rpc_clnt *nsm_client_get(struct net *net)
> +static struct rpc_clnt *nsm_client_get(struct net *net, const char *nodename)
>  {
>  	struct rpc_clnt	*clnt, *new;
>  	struct lockd_net *ln = net_generic(net, lockd_net_id);
> @@ -111,7 +112,7 @@ static struct rpc_clnt *nsm_client_get(s
>  	if (clnt != NULL)
>  		goto out;
>  
> -	clnt = new = nsm_create(net);
> +	clnt = new = nsm_create(net, nodename);
>  	if (IS_ERR(clnt))
>  		goto out;
>  
> @@ -190,19 +191,23 @@ int nsm_monitor(const struct nlm_host *h
>  	struct nsm_res	res;
>  	int		status;
>  	struct rpc_clnt *clnt;
> +	const char *nodename = NULL;
>  
>  	dprintk("lockd: nsm_monitor(%s)\n", nsm->sm_name);
>  
>  	if (nsm->sm_monitored)
>  		return 0;
>  
> +	if (host->h_rpcclnt)
> +		nodename = host->h_rpcclnt->cl_nodename;
> +
>  	/*
>  	 * Choose whether to record the caller_name or IP address of
>  	 * this peer in the local rpc.statd's database.
>  	 */
>  	nsm->sm_mon_name = nsm_use_hostnames ? nsm->sm_name : nsm->sm_addrbuf;
>  
> -	clnt = nsm_client_get(host->net);
> +	clnt = nsm_client_get(host->net, nodename);
>  	if (IS_ERR(clnt)) {
>  		status = PTR_ERR(clnt);
>  		dprintk("lockd: failed to create NSM upcall transport, "
> --- a/include/linux/sunrpc/clnt.h
> +++ b/include/linux/sunrpc/clnt.h
> @@ -57,7 +57,7 @@ struct rpc_clnt {
>  	const struct rpc_timeout *cl_timeout;	/* Timeout strategy */
>  
>  	int			cl_nodelen;	/* nodename length */
> -	char 			cl_nodename[UNX_MAXNODENAME];
> +	char 			cl_nodename[UNX_MAXNODENAME+1];
>  	struct rpc_pipe_dir_head cl_pipedir_objects;
>  	struct rpc_clnt *	cl_parent;	/* Points to parent of clones */
>  	struct rpc_rtt		cl_rtt_default;
> @@ -109,6 +109,7 @@ struct rpc_create_args {
>  	struct sockaddr		*saddress;
>  	const struct rpc_timeout *timeout;
>  	const char		*servername;
> +	const char		*nodename;
>  	const struct rpc_program *program;
>  	u32			prognumber;	/* overrides program->number */
>  	u32			version;
> --- a/net/sunrpc/clnt.c
> +++ b/net/sunrpc/clnt.c
> @@ -286,10 +286,8 @@ static struct rpc_xprt *rpc_clnt_set_tra
>  
>  static void rpc_clnt_set_nodename(struct rpc_clnt *clnt, const char *nodename)
>  {
> -	clnt->cl_nodelen = strlen(nodename);
> -	if (clnt->cl_nodelen > UNX_MAXNODENAME)
> -		clnt->cl_nodelen = UNX_MAXNODENAME;
> -	memcpy(clnt->cl_nodename, nodename, clnt->cl_nodelen);
> +	clnt->cl_nodelen = strlcpy(clnt->cl_nodename,
> +			nodename, sizeof(clnt->cl_nodename));
>  }
>  
>  static int rpc_client_register(struct rpc_clnt *clnt,
> @@ -360,6 +358,7 @@ static struct rpc_clnt * rpc_new_client(
>  	const struct rpc_version *version;
>  	struct rpc_clnt *clnt = NULL;
>  	const struct rpc_timeout *timeout;
> +	const char *nodename = args->nodename;
>  	int err;
>  
>  	/* sanity check the name before trying to print it */
> @@ -415,8 +414,10 @@ static struct rpc_clnt * rpc_new_client(
>  
>  	atomic_set(&clnt->cl_count, 1);
>  
> +	if (nodename == NULL)
> +		nodename = utsname()->nodename;
>  	/* save the nodename */
> -	rpc_clnt_set_nodename(clnt, utsname()->nodename);
> +	rpc_clnt_set_nodename(clnt, nodename);
>  
>  	err = rpc_client_register(clnt, args->authflavor, args->client_name);
>  	if (err)
> @@ -563,6 +564,7 @@ static struct rpc_clnt *__rpc_clone_clie
>  	if (xprt == NULL)
>  		goto out_err;
>  	args->servername = xprt->servername;
> +	args->nodename = clnt->cl_nodename;
>  
>  	new = rpc_new_client(args, xprt, clnt);
>  	if (IS_ERR(new)) {
> --- a/net/sunrpc/rpcb_clnt.c
> +++ b/net/sunrpc/rpcb_clnt.c
> @@ -355,7 +355,8 @@ out:
>  	return result;
>  }
>  
> -static struct rpc_clnt *rpcb_create(struct net *net, const char *hostname,
> +static struct rpc_clnt *rpcb_create(struct net *net, const char *nodename,
> +				    const char *hostname,
>  				    struct sockaddr *srvaddr, size_t salen,
>  				    int proto, u32 version)
>  {
> @@ -365,6 +366,7 @@ static struct rpc_clnt *rpcb_create(stru
>  		.address	= srvaddr,
>  		.addrsize	= salen,
>  		.servername	= hostname,
> +		.nodename	= nodename,
>  		.program	= &rpcb_program,
>  		.version	= version,
>  		.authflavor	= RPC_AUTH_UNIX,
> @@ -740,7 +742,9 @@ void rpcb_getport_async(struct rpc_task
>  	dprintk("RPC: %5u %s: trying rpcbind version %u\n",
>  		task->tk_pid, __func__, bind_version);
>  
> -	rpcb_clnt = rpcb_create(xprt->xprt_net, xprt->servername, sap, salen,
> +	rpcb_clnt = rpcb_create(xprt->xprt_net,
> +				clnt->cl_nodename,
> +				xprt->servername, sap, salen,
>  				xprt->prot, bind_version);
>  	if (IS_ERR(rpcb_clnt)) {
>  		status = PTR_ERR(rpcb_clnt);
> 
> 
> Patches currently in stable-queue which might be from trond.myklebust@xxxxxxxxxxxxxxx are
> 
> queue-3.14/sunrpc-null-utsname-dereference-on-nfs-umount-during-namespace-cleanup.patch
> queue-3.14/nfs-don-t-call-blocking-operations-while-task_running.patch
> queue-3.14/nfsv4.1-fix-a-kfree-of-uninitialised-pointers-in-decode_cb_sequence_args.patch
> --
> To unsubscribe from this list: send the line "unsubscribe stable" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]