Bug 206651

Summary: kmemleak in rpcsec_gss_krb5
Product: Networking Reporter: kircher (kircherlike)
Component: IPV4Assignee: Stephen Hemminger (stephen)
Status: NEW ---    
Severity: normal CC: bmissi, mike
Priority: P1    
Hardware: ARM   
OS: Linux   
Kernel Version: 4.19.36 Tree: Mainline
Regression: No

Description kircher 2020-02-24 03:16:28 UTC
During the loading and unloading of the kernel module, kmemleak discovered a leak problem. To reproduce this problem, you only need to enable the kmemleak option. 
CONFIG_DEBUG_KMEMLEAK=y 
CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=10000: 
Then, load and unload the module. 
modprobe rpcsec_gss_krb5 
modprobe -r rpcsec_gss_krb5: 
Repeat this process every 1000 cycles to obtain the leaked information. 
Repeat the preceding operations for 115 times. The SUnreclaim memory will increase by 85 MB. 

After checking the loading source code of rpcsec_gss_krb5, we find that the svcauth_gss_register_pseudoflavor function in the svcauth_gss.c file contains the following code segment: 

...
        test = auth_domain_lookup(name, &new->h);
        if (test != &new->h) { /* Duplicate registration */
                auth_domain_put(test);
                kfree(new->h.name);
                goto out_free_dom;
        }
        return 0;

out_free_dom:
        kfree(new);
out:
        return stat;
...

The structure of new->h.name is dynamically applied by kstrdup. When auth_domain_lookup cannot find new->h.name in the hash table, it is added to the hash table. 

When the module is unloaded, the structure in the hash table is not released accordingly. As a result, the module is leaked. I modified the gss_mech_free function to forcibly release the structure in the hash table. 

...
 	for (i = 0; i < gm->gm_pf_num; i++) {
 		pf = &gm->gm_pfs[i];
+		struct auth_domain *test;
+		test = auth_domain_find(pf->auth_domain_name);
+		if (test != NULL) {
+			test->flavour->domain_release(test);
+		}
 		kfree(pf->auth_domain_name);
...

Perform the leakage test again. The memory usage of SUnreclaim does not increase. 

I want a complete destructor to free the hash table, not by force.