mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2025-01-13 19:50:25 +03:00
Fix small sysfs leak
When zfs_kobj_init() is called with an attr_cnt of 0 only the kobj->zko_default_attrs is allocated. It subsequently won't get freed in zfs_kobj_release since the free is wrapped in a kobj->zko_attr_count != 0 conditional. Split the block in zfs_kobj_release() to make sure the kobj->zko_default_attrs are freed in this case. Additionally, fix a minor spelling mistake and typo in zfs_kobj_init() which could also cause a leak but in practice is almost certain not to fail. Reviewed-by: Richard Elling <Richard.Elling@RichardElling.com> Reviewed-by: Tim Chase <tim@chase2k.com> Reviewed-by: John Gallagher <john.gallagher@delphix.com> Reviewed-by: Don Brady <don.brady@delphix.com> Reviewed-by: George Melikov <mail@gmelikov.ru> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #7957
This commit is contained in:
parent
b954e36e51
commit
7a23c81342
@ -102,7 +102,7 @@ typedef ssize_t (*sysfs_show_func)(struct kobject *, struct attribute *,
|
||||
static void
|
||||
zfs_kobj_fini(zfs_mod_kobj_t *zkobj)
|
||||
{
|
||||
/* finialize any child kobjects */
|
||||
/* finalize any child kobjects */
|
||||
if (zkobj->zko_child_count != 0) {
|
||||
ASSERT(zkobj->zko_children);
|
||||
for (int i = 0; i < zkobj->zko_child_count; i++)
|
||||
@ -119,18 +119,19 @@ zfs_kobj_release(struct kobject *kobj)
|
||||
{
|
||||
zfs_mod_kobj_t *zkobj = container_of(kobj, zfs_mod_kobj_t, zko_kobj);
|
||||
|
||||
if (zkobj->zko_attr_count != 0) {
|
||||
ASSERT(zkobj->zko_attr_list);
|
||||
ASSERT(zkobj->zko_default_attrs);
|
||||
|
||||
if (zkobj->zko_attr_list != NULL) {
|
||||
ASSERT3S(zkobj->zko_attr_count, !=, 0);
|
||||
kmem_free(zkobj->zko_attr_list,
|
||||
ATTR_TABLE_SIZE(zkobj->zko_attr_count));
|
||||
zkobj->zko_attr_list = NULL;
|
||||
}
|
||||
|
||||
if (zkobj->zko_default_attrs != NULL) {
|
||||
kmem_free(zkobj->zko_default_attrs,
|
||||
DEFAULT_ATTR_SIZE(zkobj->zko_attr_count));
|
||||
zkobj->zko_attr_count = 0;
|
||||
zkobj->zko_attr_list = NULL;
|
||||
zkobj->zko_default_attrs = NULL;
|
||||
}
|
||||
|
||||
if (zkobj->zko_child_count != 0) {
|
||||
ASSERT(zkobj->zko_children);
|
||||
|
||||
@ -139,6 +140,8 @@ zfs_kobj_release(struct kobject *kobj)
|
||||
zkobj->zko_child_count = 0;
|
||||
zkobj->zko_children = NULL;
|
||||
}
|
||||
|
||||
zkobj->zko_attr_count = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -170,7 +173,7 @@ zfs_kobj_init(zfs_mod_kobj_t *zkobj, int attr_cnt, int child_cnt,
|
||||
zkobj->zko_default_attrs = kmem_zalloc(DEFAULT_ATTR_SIZE(attr_cnt),
|
||||
KM_SLEEP);
|
||||
if (zkobj->zko_default_attrs == NULL) {
|
||||
if (zkobj->zko_attr_list) {
|
||||
if (zkobj->zko_attr_list != NULL) {
|
||||
kmem_free(zkobj->zko_attr_list,
|
||||
ATTR_TABLE_SIZE(attr_cnt));
|
||||
}
|
||||
@ -183,9 +186,11 @@ zfs_kobj_init(zfs_mod_kobj_t *zkobj, int attr_cnt, int child_cnt,
|
||||
zkobj->zko_children = kmem_zalloc(CHILD_TABLE_SIZE(child_cnt),
|
||||
KM_SLEEP);
|
||||
if (zkobj->zko_children == NULL) {
|
||||
if (attr_cnt > 0) {
|
||||
kmem_free(zkobj->zko_attr_list,
|
||||
if (zkobj->zko_default_attrs != NULL) {
|
||||
kmem_free(zkobj->zko_default_attrs,
|
||||
DEFAULT_ATTR_SIZE(attr_cnt));
|
||||
}
|
||||
if (zkobj->zko_attr_list != NULL) {
|
||||
kmem_free(zkobj->zko_attr_list,
|
||||
ATTR_TABLE_SIZE(attr_cnt));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user