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