From 56bcf706cf91f0734899ae9de378c459a9b5af50 Mon Sep 17 00:00:00 2001 From: VinayBhaskar-V Date: Thu, 9 Jul 2026 21:30:26 +0530 Subject: [PATCH] pybind/rbd: handle non-existent groups properly in list_snaps() Calling `list_snaps()` on a non-existent group crashed the entire Python process with a `free(): invalid pointer` error. This happened because an unexpected `-ENOENT` error returned by `rbd_group_snap_list2` and the exception was raised without updating the num_group_snaps to 0 from 10. Later the Cython `__dealloc__` wrapper attempted to free garbage of uninitialized pointer spaces resulting in a crash. Fix this behavior by resetting `self.num_group_snaps` to 0 inside `GroupSnapIterator` before raising exception to prevent memory corruption and accessing uninitialized pointers during cleanup call Now `list_snaps()` consistently raise an `ObjectNotFound` error when invoked on a non-existent group. Also Extended the `TestGroups` test fixture with `self.dne_group` to validate the expected error path for `list_snaps()`. Fixes: https://tracker.ceph.com/issues/78034 Signed-off-by: VinayBhaskar-V --- src/pybind/rbd/rbd.pyx | 1 + src/test/pybind/test_rbd.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/pybind/rbd/rbd.pyx b/src/pybind/rbd/rbd.pyx index 57a11b7dc0cf..703b2f539eba 100644 --- a/src/pybind/rbd/rbd.pyx +++ b/src/pybind/rbd/rbd.pyx @@ -6143,6 +6143,7 @@ cdef class GroupSnapIterator(object): if ret >= 0: break elif ret != -errno.ERANGE: + self.num_group_snaps = 0 raise make_ex(ret, 'error listing snapshots for group %s' % group.name, group_errno_to_exception) def __iter__(self): diff --git a/src/test/pybind/test_rbd.py b/src/test/pybind/test_rbd.py index f1d4f10e391b..3bcadcb8481c 100644 --- a/src/test/pybind/test_rbd.py +++ b/src/test/pybind/test_rbd.py @@ -3078,6 +3078,7 @@ class TestGroups(object): create_group() snap_name = get_temp_snap_name() self.group = Group(ioctx, group_name) + self.dne_group = Group(ioctx, "group_does_not_exist") def teardown_method(self, method): remove_group() @@ -3191,6 +3192,7 @@ class TestGroups(object): def test_group_snap(self): global snap_name + assert_raises(ObjectNotFound, self.dne_group.list_snaps) eq([], list(self.group.list_snaps())) self.group.create_snap(snap_name) eq([snap_name], [snap['name'] for snap in self.group.list_snaps()]) -- 2.47.3