From fb1db3917ecdcfa73eca707f8faa57a2b8f9d82c Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Wed, 8 Apr 2026 14:47:40 +0200 Subject: [PATCH 01/10] lvm-dbus: Fix logic error in bd_lvm_cache_pool_convert rename condition The rename after cache pool creation was performed on failure (!ret) instead of on success (ret), unlike the analogous bd_lvm_thpool_convert which correctly uses (ret && name). This is clearly a typo. Co-Authored-By: Claude Opus 4.6 --- src/plugins/lvm/lvm-dbus.c | 2 +- tests/_lvm_cases.py | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/plugins/lvm/lvm-dbus.c b/src/plugins/lvm/lvm-dbus.c index 8b24b0da0..f6842c67f 100644 --- a/src/plugins/lvm/lvm-dbus.c +++ b/src/plugins/lvm/lvm-dbus.c @@ -3714,7 +3714,7 @@ gboolean bd_lvm_cache_pool_convert (const gchar *vg_name, const gchar *data_lv, ret = call_lvm_obj_method_sync (vg_name, VG_INTF, "CreateCachePool", params, NULL, extra, TRUE, error); - if (!ret && name) + if (ret && name) bd_lvm_lvrename (vg_name, data_lv, name, NULL, error); return ret; diff --git a/tests/_lvm_cases.py b/tests/_lvm_cases.py index 7bda93f00..0e59f0daa 100644 --- a/tests/_lvm_cases.py +++ b/tests/_lvm_cases.py @@ -1916,6 +1916,12 @@ def test_cache_pool_convert(self): succ = BlockDev.lvm_cache_pool_convert("testVG", "dataLV", "metadataLV", "testCache", None) self.assertTrue(succ) + # verify the cache pool exists under the requested name + info = BlockDev.lvm_lvinfo("testVG", "testCache") + self.assertIsNotNone(info) + self.assertEqual(info.lv_name, "testCache") + self.assertIn("C", info.attr) + @tag_test(TestTags.SLOW) def test_cache_pool_attach_detach(self): """Verify that is it possible to attach and detach a cache pool""" From f205c93d7c26f48a5766d7fb2c50dca5b000d8c5 Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Wed, 8 Apr 2026 14:48:06 +0200 Subject: [PATCH 02/10] nvdimm: Fix missing g_strdup for dev field in namespace_info_copy The copy function assigned the dev pointer directly instead of duplicating the string. This causes a double-free when both the original and the copy are freed, since bd_nvdimm_namespace_info_free calls g_free on the dev field. Co-Authored-By: Claude Opus 4.6 --- src/lib/plugin_apis/nvdimm.api | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/plugin_apis/nvdimm.api b/src/lib/plugin_apis/nvdimm.api index ec92e0af9..0e8e8e0c1 100644 --- a/src/lib/plugin_apis/nvdimm.api +++ b/src/lib/plugin_apis/nvdimm.api @@ -79,7 +79,7 @@ BDNVDIMMNamespaceInfo* bd_nvdimm_namespace_info_copy (BDNVDIMMNamespaceInfo *inf BDNVDIMMNamespaceInfo *new_info = g_new0 (BDNVDIMMNamespaceInfo, 1); - new_info->dev = info->dev; + new_info->dev = g_strdup (info->dev); new_info->mode = info->mode; new_info->size = info->size; new_info->uuid = g_strdup (info->uuid); From 2bef3482c693e7d1e586b911cafc003db77a8ab0 Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Wed, 8 Apr 2026 14:48:25 +0200 Subject: [PATCH 03/10] lvm: Fix wrong parameter type in bd_lvm_cache_stats_free The .api file declared the parameter as BDLVMLVdata instead of BDLVMCacheStats. Also added the missing NULL check that all other free functions in the codebase have. Co-Authored-By: Claude Opus 4.6 --- src/lib/plugin_apis/lvm.api | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lib/plugin_apis/lvm.api b/src/lib/plugin_apis/lvm.api index 23762dfbe..d42baaa8e 100644 --- a/src/lib/plugin_apis/lvm.api +++ b/src/lib/plugin_apis/lvm.api @@ -708,7 +708,9 @@ BDLVMCacheStats* bd_lvm_cache_stats_copy (BDLVMCacheStats *data) { * * Frees @data. */ -void bd_lvm_cache_stats_free (BDLVMLVdata *data) { +void bd_lvm_cache_stats_free (BDLVMCacheStats *data) { + if (data == NULL) + return; g_free (data); } From 0e96807ddb863c73968407d258ee821ca1b0e7b4 Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Wed, 8 Apr 2026 14:48:38 +0200 Subject: [PATCH 04/10] fs: Add missing free_cluster_count to bd_fs_vfat_info_copy The copy function omitted the free_cluster_count field, so copies always had free_cluster_count = 0 regardless of the original value. Co-Authored-By: Claude Opus 4.6 --- src/lib/plugin_apis/fs.api | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/plugin_apis/fs.api b/src/lib/plugin_apis/fs.api index 0f3ffe5e9..44ee239e1 100644 --- a/src/lib/plugin_apis/fs.api +++ b/src/lib/plugin_apis/fs.api @@ -339,6 +339,7 @@ BDFSVfatInfo* bd_fs_vfat_info_copy (BDFSVfatInfo *data) { ret->uuid = g_strdup (data->uuid); ret->cluster_size = data->cluster_size; ret->cluster_count = data->cluster_count; + ret->free_cluster_count = data->free_cluster_count; return ret; } From fe4ad85722a2c8330e1a333e875a6ea561f5af42 Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Wed, 8 Apr 2026 14:49:28 +0200 Subject: [PATCH 05/10] mdraid: Add missing total_devices to bd_md_detail_data_copy The copy function skipped the total_devices field, so copies always had total_devices = 0 regardless of the original value. Co-Authored-By: Claude Opus 4.6 --- src/lib/plugin_apis/mdraid.api | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/plugin_apis/mdraid.api b/src/lib/plugin_apis/mdraid.api index 101412813..f046bafad 100644 --- a/src/lib/plugin_apis/mdraid.api +++ b/src/lib/plugin_apis/mdraid.api @@ -172,6 +172,7 @@ BDMDDetailData* bd_md_detail_data_copy (BDMDDetailData *data) { new_data->array_size = data->array_size; new_data->use_dev_size = data->use_dev_size; new_data->raid_devices = data->raid_devices; + new_data->total_devices = data->total_devices; new_data->active_devices = data->active_devices; new_data->working_devices = data->working_devices; new_data->failed_devices = data->failed_devices; From 71284079f38ecb4c18b3f74b2da6785dae9d88bc Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Wed, 8 Apr 2026 14:49:54 +0200 Subject: [PATCH 06/10] btrfs: Use g_new0 instead of g_new for info structs The get_device_info_from_match, get_subvolume_info_from_match, and get_filesystem_info_from_match functions used g_new (unzeroed) to allocate their return structs. If regex match groups return NULL, fields like size and used would contain uninitialized garbage values. Co-Authored-By: Claude Opus 4.6 --- src/plugins/btrfs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/btrfs.c b/src/plugins/btrfs.c index e839b49e5..419088bee 100644 --- a/src/plugins/btrfs.c +++ b/src/plugins/btrfs.c @@ -172,7 +172,7 @@ gboolean bd_btrfs_is_tech_avail (BDBtrfsTech tech G_GNUC_UNUSED, guint64 mode G_ } static BDBtrfsDeviceInfo* get_device_info_from_match (GMatchInfo *match_info) { - BDBtrfsDeviceInfo *ret = g_new(BDBtrfsDeviceInfo, 1); + BDBtrfsDeviceInfo *ret = g_new0(BDBtrfsDeviceInfo, 1); gchar *item = NULL; BSSize size = NULL; BSError *error = NULL; @@ -213,7 +213,7 @@ static BDBtrfsDeviceInfo* get_device_info_from_match (GMatchInfo *match_info) { } static BDBtrfsSubvolumeInfo* get_subvolume_info_from_match (GMatchInfo *match_info) { - BDBtrfsSubvolumeInfo *ret = g_new(BDBtrfsSubvolumeInfo, 1); + BDBtrfsSubvolumeInfo *ret = g_new0(BDBtrfsSubvolumeInfo, 1); gchar *item = NULL; item = g_match_info_fetch_named (match_info, "id"); @@ -230,7 +230,7 @@ static BDBtrfsSubvolumeInfo* get_subvolume_info_from_match (GMatchInfo *match_in } static BDBtrfsFilesystemInfo* get_filesystem_info_from_match (GMatchInfo *match_info) { - BDBtrfsFilesystemInfo *ret = g_new(BDBtrfsFilesystemInfo, 1); + BDBtrfsFilesystemInfo *ret = g_new0(BDBtrfsFilesystemInfo, 1); gchar *item = NULL; BSSize size = NULL; BSError *error = NULL; From 82e4b7c448b83082b4eae94777dd2f36431b3659 Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Wed, 8 Apr 2026 14:50:28 +0200 Subject: [PATCH 07/10] crypto: Fix memory leak of label in get_subsystem_label error path When the SUBSYSTEM lookup fails, the function returned FALSE but the *label output parameter (already allocated earlier) was not freed, leaking the string. Co-Authored-By: Claude Opus 4.6 --- src/plugins/crypto.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/crypto.c b/src/plugins/crypto.c index 6acff94e3..da6f5e5e3 100644 --- a/src/plugins/crypto.c +++ b/src/plugins/crypto.c @@ -2561,6 +2561,8 @@ static gboolean get_subsystem_label (const gchar *device, gchar **subsystem, gch if (status != 0) { g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_DEVICE, "Failed to get subsystem for the device '%s'", device); + g_free (*label); + *label = NULL; blkid_free_probe (probe); synced_close (fd); return FALSE; From c4b8ae6a1ed64ed1dfa83b765c68fc5201959588 Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Wed, 8 Apr 2026 14:51:07 +0200 Subject: [PATCH 08/10] nvdimm: Fix GPtrArray leak in bd_nvdimm_list_namespaces When no namespaces are found, the function returned NULL without freeing the GPtrArray, leaking its memory. Co-Authored-By: Claude Opus 4.6 --- src/plugins/nvdimm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/nvdimm.c b/src/plugins/nvdimm.c index 962d25362..1c111eb3f 100644 --- a/src/plugins/nvdimm.c +++ b/src/plugins/nvdimm.c @@ -577,6 +577,7 @@ BDNVDIMMNamespaceInfo** bd_nvdimm_list_namespaces (const gchar *bus_name, const } if (namespaces->len == 0) { + g_ptr_array_free (namespaces, TRUE); ndctl_unref (ctx); return NULL; } From dd7b8db64b0a9808f40317e7b3b4df3a2a7b489b Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Wed, 8 Apr 2026 14:51:35 +0200 Subject: [PATCH 09/10] part: Remove dead fdisk_unref_partition call on known-NULL pointer In bd_part_create_part, the error path for fdisk_get_partitions called fdisk_unref_partition(npa), but npa is not allocated until later. The call was harmless (fdisk handles NULL) but misleading dead code. Co-Authored-By: Claude Opus 4.6 --- src/plugins/part.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/plugins/part.c b/src/plugins/part.c index faf8d4513..1068b6e68 100644 --- a/src/plugins/part.c +++ b/src/plugins/part.c @@ -991,12 +991,11 @@ BDPartSpec* bd_part_create_part (const gchar *disk, BDPartTypeReq type, guint64 if (status != 0) { g_set_error (&l_error, BD_PART_ERROR, BD_PART_ERROR_FAIL, "Failed to get existing partitions on the device: %s", strerror_l (-status, c_locale)); - fdisk_unref_partition (npa); close_context (cxt); bd_utils_report_finished (progress_id, l_error->message); g_propagate_error (error, l_error); return NULL; - } + } npa = fdisk_new_partition (); if (!npa) { From 4de29e4ffa328bd2297b2ce1bb9bf396acf84a3e Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Wed, 8 Apr 2026 14:51:55 +0200 Subject: [PATCH 10/10] crypto: Remove dead crypt_free call on known-NULL pointer In bd_crypto_tc_open, the context type validation error path called crypt_free(cd), but cd is not initialized until crypt_init is called further down. The call was harmless but misleading dead code. Co-Authored-By: Claude Opus 4.6 --- src/plugins/crypto.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/crypto.c b/src/plugins/crypto.c index da6f5e5e3..e801e30a3 100644 --- a/src/plugins/crypto.c +++ b/src/plugins/crypto.c @@ -3287,7 +3287,6 @@ gboolean bd_crypto_tc_open_flags (const gchar *device, const gchar *name, BDCryp "Only 'passphrase' context type is valid for TC open."); bd_utils_report_finished (progress_id, l_error->message); g_propagate_error (error, l_error); - crypt_free (cd); return FALSE; }