FreeBSD: Fix memory leaks in kstats

Don't handle (incorrectly) kmem_zalloc() failure.  With KM_SLEEP,
will never return NULL.

Free the data allocated for non-virtual kstats when deleting the object.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Signed-off-by: Ryan Moeller <ryan@iXsystems.com>
Closes #11767
This commit is contained in:
Ryan Moeller 2021-03-18 00:55:18 -04:00 committed by GitHub
parent 1daad98176
commit ec3e4c6784
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -299,15 +299,10 @@ __kstat_create(const char *module, int instance, const char *name,
panic("Undefined kstat type %d\n", ksp->ks_type); panic("Undefined kstat type %d\n", ksp->ks_type);
} }
if (ksp->ks_flags & KSTAT_FLAG_VIRTUAL) { if (ksp->ks_flags & KSTAT_FLAG_VIRTUAL)
ksp->ks_data = NULL; ksp->ks_data = NULL;
} else { else
ksp->ks_data = kmem_zalloc(ksp->ks_data_size, KM_SLEEP); ksp->ks_data = kmem_zalloc(ksp->ks_data_size, KM_SLEEP);
if (ksp->ks_data == NULL) {
kmem_free(ksp, sizeof (*ksp));
ksp = NULL;
}
}
/* /*
* Some kstats use a module name like "zfs/poolname" to distinguish a * Some kstats use a module name like "zfs/poolname" to distinguish a
@ -509,6 +504,8 @@ kstat_delete(kstat_t *ksp)
sysctl_ctx_free(&ksp->ks_sysctl_ctx); sysctl_ctx_free(&ksp->ks_sysctl_ctx);
ksp->ks_lock = NULL; ksp->ks_lock = NULL;
mutex_destroy(&ksp->ks_private_lock); mutex_destroy(&ksp->ks_private_lock);
if (!(ksp->ks_flags & KSTAT_FLAG_VIRTUAL))
kmem_free(ksp->ks_data, ksp->ks_data_size);
free(ksp, M_KSTAT); free(ksp, M_KSTAT);
} }