diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-08-26 16:05:11 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-08-30 09:19:37 -0400 |
commit | 6b2fddd3e7f7cd437fb234407d7504fd22caf064 (patch) | |
tree | e0c82f4b204db63bd37194f28df384deca6f55ba /net/sunrpc | |
parent | e726340ac9cf6bb5b3f92a064664e10cd2b748de (diff) |
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 <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc')
-rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 32 |
1 files 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) | |||
796 | struct gss_auth *gss_auth; | 796 | struct gss_auth *gss_auth; |
797 | 797 | ||
798 | gss_auth = container_of(auth, struct gss_auth, rpc_auth); | 798 | gss_auth = container_of(auth, struct gss_auth, rpc_auth); |
799 | if (gss_auth->pipe[0]->dentry) | 799 | if (gss_auth->pipe[0]->dentry) { |
800 | rpc_unlink(gss_auth->pipe[0]->dentry); | 800 | rpc_unlink(gss_auth->pipe[0]->dentry); |
801 | if (gss_auth->pipe[1]->dentry) | 801 | gss_auth->pipe[0]->dentry = NULL; |
802 | } | ||
803 | if (gss_auth->pipe[1]->dentry) { | ||
802 | rpc_unlink(gss_auth->pipe[1]->dentry); | 804 | rpc_unlink(gss_auth->pipe[1]->dentry); |
805 | gss_auth->pipe[1]->dentry = NULL; | ||
806 | } | ||
803 | } | 807 | } |
804 | 808 | ||
805 | static int gss_pipes_dentries_create(struct rpc_auth *auth) | 809 | static int gss_pipes_dentries_create(struct rpc_auth *auth) |
@@ -807,26 +811,30 @@ static int gss_pipes_dentries_create(struct rpc_auth *auth) | |||
807 | int err; | 811 | int err; |
808 | struct gss_auth *gss_auth; | 812 | struct gss_auth *gss_auth; |
809 | struct rpc_clnt *clnt; | 813 | struct rpc_clnt *clnt; |
814 | struct dentry *dentry; | ||
810 | 815 | ||
811 | gss_auth = container_of(auth, struct gss_auth, rpc_auth); | 816 | gss_auth = container_of(auth, struct gss_auth, rpc_auth); |
812 | clnt = gss_auth->client; | 817 | clnt = gss_auth->client; |
813 | 818 | ||
814 | gss_auth->pipe[1]->dentry = rpc_mkpipe_dentry(clnt->cl_dentry, | 819 | dentry = rpc_mkpipe_dentry(clnt->cl_dentry, "gssd", |
815 | "gssd", | 820 | clnt, gss_auth->pipe[1]); |
816 | clnt, gss_auth->pipe[1]); | 821 | if (IS_ERR(dentry)) { |
817 | if (IS_ERR(gss_auth->pipe[1]->dentry)) | 822 | err = PTR_ERR(dentry); |
818 | return PTR_ERR(gss_auth->pipe[1]->dentry); | 823 | goto err; |
819 | gss_auth->pipe[0]->dentry = rpc_mkpipe_dentry(clnt->cl_dentry, | 824 | } |
820 | gss_auth->mech->gm_name, | 825 | gss_auth->pipe[1]->dentry = dentry; |
821 | clnt, gss_auth->pipe[0]); | 826 | dentry = rpc_mkpipe_dentry(clnt->cl_dentry, gss_auth->mech->gm_name, |
822 | if (IS_ERR(gss_auth->pipe[0]->dentry)) { | 827 | clnt, gss_auth->pipe[0]); |
823 | err = PTR_ERR(gss_auth->pipe[0]->dentry); | 828 | if (IS_ERR(dentry)) { |
829 | err = PTR_ERR(dentry); | ||
824 | goto err_unlink_pipe_1; | 830 | goto err_unlink_pipe_1; |
825 | } | 831 | } |
826 | return 0; | 832 | return 0; |
827 | 833 | ||
828 | err_unlink_pipe_1: | 834 | err_unlink_pipe_1: |
829 | rpc_unlink(gss_auth->pipe[1]->dentry); | 835 | rpc_unlink(gss_auth->pipe[1]->dentry); |
836 | gss_auth->pipe[1]->dentry = NULL; | ||
837 | err: | ||
830 | return err; | 838 | return err; |
831 | } | 839 | } |
832 | 840 | ||