Аудит от GPT-5-5 от fox - для истории #76

Closed
opened 2026-06-14 22:27:18 +03:00 by vitalif · 1 comment
Owner

Audit Result

Read-only audit of commit c16f955a519ecce39c2538a9b1ffde36d3133b71, excluding KV, NFS, NBD, and ublk. No builds, tests, edits, or artifacts.

13 CONFIRMED, 3 NEEDS MORE CONTEXT, 0 FALSE POSITIVES. Every finding received independent devil’s-advocate and exploit-scenario review.

Critical Findings

  1. Parity-less degraded EC writes destroy allocation bitmaps — CONFIRMED. Partial writes with all parity roles absent replace surviving-role bitmaps with mostly zero data, causing subsequent reads to return parent/zero instead of existing bytes. Deterministic under this geometry. osd_rmw.cpp, osd_primary_subops.cpp, blockstore_heap.cpp

  2. ISA-L decoder cache hits use zero row stride — CONFIRMED. item_size is initialized only on cache misses; later degraded reads with multiple missing data roles can decode using the wrong matrix row. This silently returns or persists a valid but incorrect codeword. osd_rmw.cpp, osd_rmw.cpp

  3. SYNC can acknowledge metadata not covered by any flush — CONFIRMED. A metadata write may complete after an earlier fsync while SYNC has already cleared its dirty counter; a later journal-only SYNC can then mark the associated LSN durable. Power loss can lose acknowledged writes or resurrect deletes. blockstore_write.cpp, blockstore_impl.cpp, blockstore_sync.cpp

  4. Legacy concurrent read/flush frees the wrong allocator block — CONFIRMED. The read path stores a byte offset but later passes it as a block index. A different live object can be freed and overwritten while its metadata continues referencing that block. read.cpp, flush.cpp, allocator.cpp

  5. All metadata formats publish the header before clearing old metadata — CONFIRMED. A crash during initialization leaves a valid new header over stale CRC-valid entries. Restart can load phantom objects and promote stale high-LSN versions. blockstore_init.cpp, v1/init.cpp, disk_tool_prepare.cpp

  6. Checksum compaction blesses latent corruption — CONFIRMED. Partial checksum-block updates intentionally skip validation of untouched old bytes; compaction recalculates and persists checksums over those bytes. Existing corruption consequently becomes permanently checksum-valid. blockstore_read.cpp, blockstore_flush.cpp, blockstore_heap.cpp

  7. Legacy journal flushing launders corrupted data — CONFIRMED. Format-2 detects journal corruption but then writes the mutated buffer into the data area and generates matching metadata checksums. Future reads accept the corruption. v1/flush.cpp, v1/flush.cpp

  8. Unstable deletes are omitted from replay and falsely synchronized — CONFIRMED. Zero-length deletes are absent from the write cache; after primary disconnection, SYNC removes the OSD from dirty_osds and succeeds without replaying the delete. Power loss can resurrect the old object. cluster_client.cpp, cluster_client_wb.cpp

  9. Scrub-known inconsistent replicas remain readable — CONFIRMED. Scrub records the inconsistency, but normal read placement ignores that state and returns whichever same-version replica is selected. Different primaries may silently return different payloads. osd_scrub.cpp, osd_primary.cpp, osd_primary_subops.cpp

  10. Writeback mode treats DELETE as a successful no-op — CONFIRMED. A zero-length delete returns success without recording or sending anything. Every delete under the affected configuration leaves the original object present. cluster_client.cpp, cluster_client_wb.cpp

High Findings

  1. Degraded EC scrub writes beyond its heap allocation — CONFIRMED. When k < live roles < n, temporary stripes are allocated by compact count but indexed by original role. Example: EC 4+2 with five live roles deterministically corrupts heap memory. osd_rmw.cpp, osd_rmw.cpp, osd_scrub.cpp

  2. Scrub never compares external allocation bitmaps — CONFIRMED. Replicas with identical bytes but divergent logical-allocation metadata pass scrub. Chained and snapshot reads can therefore return different parent, zero, or local data without detection. osd_scrub.cpp, osd_rmw.cpp

  3. Repeated scrub clears known corruption — CONFIRMED. A still-failing replica already marked LOC_CORRUPTED can enter the clearing path on the next scrub. EC compact indexing can additionally access outside the stripe array. osd_scrub.cpp

Needs More Context

  1. Torn format-3 metadata blocks. The format lacks block-level generation/COW protection and can accept a valid old/new sector mixture. Verdict depends on the cloud volume’s power-loss atomic write unit. blockstore_heap.cpp

  2. Positive short initialization I/O. All formats accept any nonnegative result as complete. Confirming production reachability requires the kernel, device driver, and cloud-volume short-I/O guarantees. blockstore_init.cpp, v1/init.cpp

  3. Public C deletion API hides LEFT_ON_DEAD. Stale-copy resurrection is possible if the external metadata consumer treats success as an atomic tombstone, but that consumer is outside this repository. vitastor_c.cpp, osd_primary.cpp

Linux ordering basis for finding 3: writeback cache controls, dm-log-writes ordering.

**Audit Result** Read-only audit of commit `c16f955a519ecce39c2538a9b1ffde36d3133b71`, excluding KV, NFS, NBD, and ublk. No builds, tests, edits, or artifacts. **13 CONFIRMED, 3 NEEDS MORE CONTEXT, 0 FALSE POSITIVES.** Every finding received independent devil’s-advocate and exploit-scenario review. **Critical Findings** 1. **Parity-less degraded EC writes destroy allocation bitmaps — CONFIRMED.** Partial writes with all parity roles absent replace surviving-role bitmaps with mostly zero data, causing subsequent reads to return parent/zero instead of existing bytes. Deterministic under this geometry. [osd_rmw.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/osd/osd_rmw.cpp?display=source#L655), [osd_primary_subops.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/osd/osd_primary_subops.cpp?display=source#L159), [blockstore_heap.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/blockstore/blockstore_heap.cpp?display=source#L1572) 2. **ISA-L decoder cache hits use zero row stride — CONFIRMED.** `item_size` is initialized only on cache misses; later degraded reads with multiple missing data roles can decode using the wrong matrix row. This silently returns or persists a valid but incorrect codeword. [osd_rmw.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/osd/osd_rmw.cpp?display=source#L327), [osd_rmw.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/osd/osd_rmw.cpp?display=source#L397) 3. **SYNC can acknowledge metadata not covered by any flush — CONFIRMED.** A metadata write may complete after an earlier fsync while SYNC has already cleared its dirty counter; a later journal-only SYNC can then mark the associated LSN durable. Power loss can lose acknowledged writes or resurrect deletes. [blockstore_write.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/blockstore/blockstore_write.cpp?display=source#L20), [blockstore_impl.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/blockstore/blockstore_impl.cpp?display=source#L134), [blockstore_sync.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/blockstore/blockstore_sync.cpp?display=source#L52) 4. **Legacy concurrent read/flush frees the wrong allocator block — CONFIRMED.** The read path stores a byte offset but later passes it as a block index. A different live object can be freed and overwritten while its metadata continues referencing that block. [read.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/blockstore/v1/read.cpp?display=source#L681), [flush.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/blockstore/v1/flush.cpp?display=source#L1293), [allocator.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/util/allocator.cpp?display=source#L55) 5. **All metadata formats publish the header before clearing old metadata — CONFIRMED.** A crash during initialization leaves a valid new header over stale CRC-valid entries. Restart can load phantom objects and promote stale high-LSN versions. [blockstore_init.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/blockstore/blockstore_init.cpp?display=source#L73), [v1/init.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/blockstore/v1/init.cpp?display=source#L81), [disk_tool_prepare.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/disk_tool/disk_tool_prepare.cpp?display=source#L274) 6. **Checksum compaction blesses latent corruption — CONFIRMED.** Partial checksum-block updates intentionally skip validation of untouched old bytes; compaction recalculates and persists checksums over those bytes. Existing corruption consequently becomes permanently checksum-valid. [blockstore_read.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/blockstore/blockstore_read.cpp?display=source#L429), [blockstore_flush.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/blockstore/blockstore_flush.cpp?display=source#L512), [blockstore_heap.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/blockstore/blockstore_heap.cpp?display=source#L1717) 7. **Legacy journal flushing launders corrupted data — CONFIRMED.** Format-2 detects journal corruption but then writes the mutated buffer into the data area and generates matching metadata checksums. Future reads accept the corruption. [v1/flush.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/blockstore/v1/flush.cpp?display=source#L805), [v1/flush.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/blockstore/v1/flush.cpp?display=source#L921) 8. **Unstable deletes are omitted from replay and falsely synchronized — CONFIRMED.** Zero-length deletes are absent from the write cache; after primary disconnection, SYNC removes the OSD from `dirty_osds` and succeeds without replaying the delete. Power loss can resurrect the old object. [cluster_client.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/client/cluster_client.cpp?display=source#L1463), [cluster_client_wb.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/client/cluster_client_wb.cpp?display=source#L84) 9. **Scrub-known inconsistent replicas remain readable — CONFIRMED.** Scrub records the inconsistency, but normal read placement ignores that state and returns whichever same-version replica is selected. Different primaries may silently return different payloads. [osd_scrub.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/osd/osd_scrub.cpp?display=source#L499), [osd_primary.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/osd/osd_primary.cpp?display=source#L184), [osd_primary_subops.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/osd/osd_primary_subops.cpp?display=source#L118) 10. **Writeback mode treats DELETE as a successful no-op — CONFIRMED.** A zero-length delete returns success without recording or sending anything. Every delete under the affected configuration leaves the original object present. [cluster_client.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/client/cluster_client.cpp?display=source#L774), [cluster_client_wb.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/client/cluster_client_wb.cpp?display=source#L84) **High Findings** 11. **Degraded EC scrub writes beyond its heap allocation — CONFIRMED.** When `k < live roles < n`, temporary stripes are allocated by compact count but indexed by original role. Example: EC 4+2 with five live roles deterministically corrupts heap memory. [osd_rmw.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/osd/osd_rmw.cpp?display=source#L1204), [osd_rmw.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/osd/osd_rmw.cpp?display=source#L1341), [osd_scrub.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/osd/osd_scrub.cpp?display=source#L397) 12. **Scrub never compares external allocation bitmaps — CONFIRMED.** Replicas with identical bytes but divergent logical-allocation metadata pass scrub. Chained and snapshot reads can therefore return different parent, zero, or local data without detection. [osd_scrub.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/osd/osd_scrub.cpp?display=source#L474), [osd_rmw.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/osd/osd_rmw.cpp?display=source#L1244) 13. **Repeated scrub clears known corruption — CONFIRMED.** A still-failing replica already marked `LOC_CORRUPTED` can enter the clearing path on the next scrub. EC compact indexing can additionally access outside the stripe array. [osd_scrub.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/osd/osd_scrub.cpp?display=source#L625) **Needs More Context** 14. **Torn format-3 metadata blocks.** The format lacks block-level generation/COW protection and can accept a valid old/new sector mixture. Verdict depends on the cloud volume’s power-loss atomic write unit. [blockstore_heap.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/blockstore/blockstore_heap.cpp?display=source#L292) 15. **Positive short initialization I/O.** All formats accept any nonnegative result as complete. Confirming production reachability requires the kernel, device driver, and cloud-volume short-I/O guarantees. [blockstore_init.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/blockstore/blockstore_init.cpp?display=source#L26), [v1/init.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/blockstore/v1/init.cpp?display=source#L33) 16. **Public C deletion API hides `LEFT_ON_DEAD`.** Stale-copy resurrection is possible if the external metadata consumer treats success as an atomic tombstone, but that consumer is outside this repository. [vitastor_c.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/client/vitastor_c.cpp?display=source#L332), [osd_primary.cpp](https://git.yourcmc.ru/vitalif/vitastor/src/commit/c16f955a519ecce39c2538a9b1ffde36d3133b71/src/osd/osd_primary.cpp?display=source#L834) Linux ordering basis for finding 3: [writeback cache controls](https://docs.kernel.org/block/writeback_cache_control.html), [dm-log-writes ordering](https://docs.kernel.org/admin-guide/device-mapper/log-writes.html#log-ordering).
Author
Owner

Итог:
Мега годный анализ.
Не подтверждены пункты 3, 6, 8, 9, 10, 14, 16.
Всё остальное очень годное, особенно мне понравилось замечание про то, что скрабы не проверяли битмапы.
Всё исправлено и закоммичено, написаны регрессионные тесты, пойманы дополнительные баги по цепочке и тоже исправлены.))

Итог: Мега годный анализ. Не подтверждены пункты 3, 6, 8, 9, 10, 14, 16. Всё остальное очень годное, особенно мне понравилось замечание про то, что скрабы не проверяли битмапы. Всё исправлено и закоммичено, написаны регрессионные тесты, пойманы дополнительные баги по цепочке и тоже исправлены.))
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: vitalif/vitastor#76
No description provided.