Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6b2fddd3 authored by Trond Myklebust's avatar Trond Myklebust
Browse files

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: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent e726340a
Loading
Loading
Loading
Loading
+20 −12
Original line number Diff line number Diff line
@@ -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",
	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,
	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(gss_auth->pipe[0]->dentry)) {
		err = PTR_ERR(gss_auth->pipe[0]->dentry);
	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;
}