Found by Opus 4.6:
In get_obj() (lines 417-446), when obj_iter ==
list_results.objs.end() and the listing is truncated, the code calls
fetch() to get the next batch. fetch() sets obj_iter =
list_results.objs.begin(). But if the new fetch returns zero objects
(possible if objects were deleted between listing batches, or due to
filtering/race conditions), then begin() == end() and the code falls
through to line 437:
if (obj_iter->key.name == pre_obj.key.name) {
This dereferences end() — undefined behavior / crash. The
return-value check at line 445 (return obj_iter !=
list_results.objs.end()) comes too late; the dereference already
happened.
Fixes: https://tracker.ceph.com/issues/76790
Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
Assisted-by: Claude Code, Opus 4.6 1M
}
}
delay(dpp);
+ if (obj_iter == list_results.objs.end()) {
+ return false;
+ }
}
if (obj_iter->key.name == pre_obj.key.name) {
/* returning address of entry in objs */
*obj = &(*obj_iter);
- return obj_iter != list_results.objs.end();
+ return true;
}
rgw_bucket_dir_entry get_prev_obj() {