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

Commit 8f2c1ab1 authored by NeilBrown's avatar NeilBrown Committed by Greg Kroah-Hartman
Browse files

sunrpc: clean up properly in gss_mech_unregister()

commit 24c5efe41c29ee3e55bcf5a1c9f61ca8709622e8 upstream.

gss_mech_register() calls svcauth_gss_register_pseudoflavor() for each
flavour, but gss_mech_unregister() does not call auth_domain_put().
This is unbalanced and makes it impossible to reload the module.

Change svcauth_gss_register_pseudoflavor() to return the registered
auth_domain, and save it for later release.

Cc: stable@vger.kernel.org (v2.6.12+)
Link: https://bugzilla.kernel.org/show_bug.cgi?id=206651


Signed-off-by: default avatarNeilBrown <neilb@suse.de>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c894f31a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ struct pf_desc {
	u32	service;
	char	*name;
	char	*auth_domain_name;
	struct auth_domain *domain;
	bool	datatouch;
};

+2 −1
Original line number Diff line number Diff line
@@ -21,7 +21,8 @@ int gss_svc_init(void);
void gss_svc_shutdown(void);
int gss_svc_init_net(struct net *net);
void gss_svc_shutdown_net(struct net *net);
int svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name);
struct auth_domain *svcauth_gss_register_pseudoflavor(u32 pseudoflavor,
						      char *name);
u32 svcauth_gss_flavor(struct auth_domain *dom);

#endif /* __KERNEL__ */
+9 −3
Original line number Diff line number Diff line
@@ -61,6 +61,8 @@ gss_mech_free(struct gss_api_mech *gm)

	for (i = 0; i < gm->gm_pf_num; i++) {
		pf = &gm->gm_pfs[i];
		if (pf->domain)
			auth_domain_put(pf->domain);
		kfree(pf->auth_domain_name);
		pf->auth_domain_name = NULL;
	}
@@ -83,6 +85,7 @@ make_auth_domain_name(char *name)
static int
gss_mech_svc_setup(struct gss_api_mech *gm)
{
	struct auth_domain *dom;
	struct pf_desc *pf;
	int i, status;

@@ -92,11 +95,14 @@ gss_mech_svc_setup(struct gss_api_mech *gm)
		status = -ENOMEM;
		if (pf->auth_domain_name == NULL)
			goto out;
		status = svcauth_gss_register_pseudoflavor(pf->pseudoflavor,
							pf->auth_domain_name);
		if (status)
		dom = svcauth_gss_register_pseudoflavor(
			pf->pseudoflavor, pf->auth_domain_name);
		if (IS_ERR(dom)) {
			status = PTR_ERR(dom);
			goto out;
		}
		pf->domain = dom;
	}
	return 0;
out:
	gss_mech_free(gm);
+6 −6
Original line number Diff line number Diff line
@@ -779,7 +779,7 @@ u32 svcauth_gss_flavor(struct auth_domain *dom)

EXPORT_SYMBOL_GPL(svcauth_gss_flavor);

int
struct auth_domain *
svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name)
{
	struct gss_domain	*new;
@@ -802,17 +802,17 @@ svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name)
			name);
		stat = -EADDRINUSE;
		auth_domain_put(test);
		kfree(new->h.name);
		goto out_free_dom;
		goto out_free_name;
	}
	return 0;
	return test;

out_free_name:
	kfree(new->h.name);
out_free_dom:
	kfree(new);
out:
	return stat;
	return ERR_PTR(stat);
}

EXPORT_SYMBOL_GPL(svcauth_gss_register_pseudoflavor);

static inline int