lib/blob: prevent overflowing uint32_t when clearing cluster data

When blob is deleted or reduced in size, the trimmed clusters
are cleared using bs_batch_clear_dev().

blob_persist_clear_clusters() iterated over the clusters
and batched each contigous set of LBA.

The lba_count is of the uint32_t type, long enough
contigous set of LBA could overflow it.
As a result that range would only be cleared with the
overflown value.

This patch prevents that overflow from occuring by
verifying against UINT32_MAX.

This is already addressed with an API change in SPDK 21.10:
(f01146ae)blob: use uint64_t for unmap and write_zeroes lba count

Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Change-Id: I17282a2a81587c26b7e89a74dcc6a9c8a017ce15
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/9971
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Tomasz Zawadzki 2021-10-22 10:36:11 +02:00
parent ca470ff844
commit 752ceb0c12

View File

@ -1765,7 +1765,7 @@ blob_persist_clear_clusters(spdk_bs_sequence_t *seq, struct spdk_blob_persist_ct
spdk_bs_batch_t *batch; spdk_bs_batch_t *batch;
size_t i; size_t i;
uint64_t lba; uint64_t lba;
uint32_t lba_count; uint64_t lba_count;
/* Clusters don't move around in blobs. The list shrinks or grows /* Clusters don't move around in blobs. The list shrinks or grows
* at the end, but no changes ever occur in the middle of the list. * at the end, but no changes ever occur in the middle of the list.
@ -1778,9 +1778,10 @@ blob_persist_clear_clusters(spdk_bs_sequence_t *seq, struct spdk_blob_persist_ct
lba_count = 0; lba_count = 0;
for (i = blob->active.num_clusters; i < blob->active.cluster_array_size; i++) { for (i = blob->active.num_clusters; i < blob->active.cluster_array_size; i++) {
uint64_t next_lba = blob->active.clusters[i]; uint64_t next_lba = blob->active.clusters[i];
uint32_t next_lba_count = bs_cluster_to_lba(bs, 1); uint64_t next_lba_count = bs_cluster_to_lba(bs, 1);
if (next_lba > 0 && (lba + lba_count) == next_lba) { if (next_lba > 0 && (lba + lba_count) == next_lba &&
(lba_count + next_lba_count <= UINT32_MAX)) {
/* This cluster is contiguous with the previous one. */ /* This cluster is contiguous with the previous one. */
lba_count += next_lba_count; lba_count += next_lba_count;
continue; continue;