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 <vvarada@redhat.com>
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):
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()
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()])