From 6b2fddd3e7f7cd437fb234407d7504fd22caf064 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 26 Aug 2013 16:05:11 -0400 Subject: [PATCH] RPCSEC_GSS: Fix an Oopsable condition when creating/destroying pipefs objects If an error condition occurs on rpc_pipefs creation, or the user mounts rpc_pipefs and then unmounts it, then the dentries in struct gss_auth need to be reset to NULL so that a second call to gss_pipes_dentries_destroy doesn't try to free them again. Signed-off-by: Trond Myklebust --- net/sunrpc/auth_gss/auth_gss.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 632380336660..c0d36bb87d3e 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -796,10 +796,14 @@ static void gss_pipes_dentries_destroy(struct rpc_auth *auth) struct gss_auth *gss_auth; gss_auth = container_of(auth, struct gss_auth, rpc_auth); - if (gss_auth->pipe[0]->dentry) + if (gss_auth->pipe[0]->dentry) { rpc_unlink(gss_auth->pipe[0]->dentry); - if (gss_auth->pipe[1]->dentry) + gss_auth->pipe[0]->dentry = NULL; + } + if (gss_auth->pipe[1]->dentry) { rpc_unlink(gss_auth->pipe[1]->dentry); + gss_auth->pipe[1]->dentry = NULL; + } } static int gss_pipes_dentries_create(struct rpc_auth *auth) @@ -807,26 +811,30 @@ static int gss_pipes_dentries_create(struct rpc_auth *auth) int err; struct gss_auth *gss_auth; struct rpc_clnt *clnt; + struct dentry *dentry; gss_auth = container_of(auth, struct gss_auth, rpc_auth); clnt = gss_auth->client; - gss_auth->pipe[1]->dentry = rpc_mkpipe_dentry(clnt->cl_dentry, - "gssd", - clnt, gss_auth->pipe[1]); - if (IS_ERR(gss_auth->pipe[1]->dentry)) - return PTR_ERR(gss_auth->pipe[1]->dentry); - gss_auth->pipe[0]->dentry = rpc_mkpipe_dentry(clnt->cl_dentry, - gss_auth->mech->gm_name, - clnt, gss_auth->pipe[0]); - if (IS_ERR(gss_auth->pipe[0]->dentry)) { - err = PTR_ERR(gss_auth->pipe[0]->dentry); + dentry = rpc_mkpipe_dentry(clnt->cl_dentry, "gssd", + clnt, gss_auth->pipe[1]); + if (IS_ERR(dentry)) { + err = PTR_ERR(dentry); + goto err; + } + gss_auth->pipe[1]->dentry = dentry; + dentry = rpc_mkpipe_dentry(clnt->cl_dentry, gss_auth->mech->gm_name, + clnt, gss_auth->pipe[0]); + if (IS_ERR(dentry)) { + err = PTR_ERR(dentry); goto err_unlink_pipe_1; } return 0; err_unlink_pipe_1: rpc_unlink(gss_auth->pipe[1]->dentry); + gss_auth->pipe[1]->dentry = NULL; +err: return err; }