sunrpc: clean up properly in gss_mech_unregister()
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: NeilBrown <neilb@suse.de> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
parent
d47a5dc288
commit
24c5efe41c
|
@ -84,6 +84,7 @@ struct pf_desc {
|
||||||
u32 service;
|
u32 service;
|
||||||
char *name;
|
char *name;
|
||||||
char *auth_domain_name;
|
char *auth_domain_name;
|
||||||
|
struct auth_domain *domain;
|
||||||
bool datatouch;
|
bool datatouch;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,8 @@ int gss_svc_init(void);
|
||||||
void gss_svc_shutdown(void);
|
void gss_svc_shutdown(void);
|
||||||
int gss_svc_init_net(struct net *net);
|
int gss_svc_init_net(struct net *net);
|
||||||
void gss_svc_shutdown_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);
|
u32 svcauth_gss_flavor(struct auth_domain *dom);
|
||||||
|
|
||||||
#endif /* _LINUX_SUNRPC_SVCAUTH_GSS_H */
|
#endif /* _LINUX_SUNRPC_SVCAUTH_GSS_H */
|
||||||
|
|
|
@ -37,6 +37,8 @@ gss_mech_free(struct gss_api_mech *gm)
|
||||||
|
|
||||||
for (i = 0; i < gm->gm_pf_num; i++) {
|
for (i = 0; i < gm->gm_pf_num; i++) {
|
||||||
pf = &gm->gm_pfs[i];
|
pf = &gm->gm_pfs[i];
|
||||||
|
if (pf->domain)
|
||||||
|
auth_domain_put(pf->domain);
|
||||||
kfree(pf->auth_domain_name);
|
kfree(pf->auth_domain_name);
|
||||||
pf->auth_domain_name = NULL;
|
pf->auth_domain_name = NULL;
|
||||||
}
|
}
|
||||||
|
@ -59,6 +61,7 @@ make_auth_domain_name(char *name)
|
||||||
static int
|
static int
|
||||||
gss_mech_svc_setup(struct gss_api_mech *gm)
|
gss_mech_svc_setup(struct gss_api_mech *gm)
|
||||||
{
|
{
|
||||||
|
struct auth_domain *dom;
|
||||||
struct pf_desc *pf;
|
struct pf_desc *pf;
|
||||||
int i, status;
|
int i, status;
|
||||||
|
|
||||||
|
@ -68,10 +71,13 @@ gss_mech_svc_setup(struct gss_api_mech *gm)
|
||||||
status = -ENOMEM;
|
status = -ENOMEM;
|
||||||
if (pf->auth_domain_name == NULL)
|
if (pf->auth_domain_name == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
status = svcauth_gss_register_pseudoflavor(pf->pseudoflavor,
|
dom = svcauth_gss_register_pseudoflavor(
|
||||||
pf->auth_domain_name);
|
pf->pseudoflavor, pf->auth_domain_name);
|
||||||
if (status)
|
if (IS_ERR(dom)) {
|
||||||
|
status = PTR_ERR(dom);
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
pf->domain = dom;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
out:
|
out:
|
||||||
|
|
|
@ -809,7 +809,7 @@ u32 svcauth_gss_flavor(struct auth_domain *dom)
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(svcauth_gss_flavor);
|
EXPORT_SYMBOL_GPL(svcauth_gss_flavor);
|
||||||
|
|
||||||
int
|
struct auth_domain *
|
||||||
svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name)
|
svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name)
|
||||||
{
|
{
|
||||||
struct gss_domain *new;
|
struct gss_domain *new;
|
||||||
|
@ -832,17 +832,17 @@ svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name)
|
||||||
name);
|
name);
|
||||||
stat = -EADDRINUSE;
|
stat = -EADDRINUSE;
|
||||||
auth_domain_put(test);
|
auth_domain_put(test);
|
||||||
kfree(new->h.name);
|
goto out_free_name;
|
||||||
goto out_free_dom;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return test;
|
||||||
|
|
||||||
|
out_free_name:
|
||||||
|
kfree(new->h.name);
|
||||||
out_free_dom:
|
out_free_dom:
|
||||||
kfree(new);
|
kfree(new);
|
||||||
out:
|
out:
|
||||||
return stat;
|
return ERR_PTR(stat);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(svcauth_gss_register_pseudoflavor);
|
EXPORT_SYMBOL_GPL(svcauth_gss_register_pseudoflavor);
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
|
|
Loading…
Reference in New Issue