114 lines
3.9 KiB
Diff
114 lines
3.9 KiB
Diff
From 20a049ac3267240de7ffcfb55cf58c08fe7d88a6 Mon Sep 17 00:00:00 2001
|
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
|
Date: Fri, 27 Jun 2025 11:38:24 +0200
|
|
Subject: [PATCH 25/47] libdm-stats: fix type mismatch in bit operations
|
|
|
|
The stats implementation was using uint64_t for group_id and loop variables
|
|
while calling dm_bit_* functions that return int types. This created a
|
|
potential issue where large values could be incorrectly handled due to
|
|
implicit casting between signed and unsigned types.
|
|
|
|
Changes:
|
|
- Change loop variables from uint64_t to int in _stats_group_tag_len()
|
|
- Change loop variable from uint64_t to int in _stats_clear_group_regions()
|
|
- Change loop variables from uint64_t to int in dm_stats_get_counter()
|
|
- Change loop variable from uint64_t to int in dm_stats_get_region_len()
|
|
- Fix _stats_create_group() to properly handle dm_bit_get_first() return value
|
|
|
|
This ensures consistent type usage and prevents potential issues with
|
|
values exceeding INT_MAX (2^31 - 1). Also this limitats group_id to 31 bits
|
|
as a constraint that may need addressing in the future.
|
|
|
|
FIXME: Maybe consider implementing 64-bit variants of dm_bit functions or
|
|
documenting this limitation more prominently is this ever become an
|
|
issue...
|
|
|
|
(cherry picked from commit 2dec6f5493e573b7a4012708931226bcbc9af32f)
|
|
---
|
|
libdm/libdm-stats.c | 25 +++++++++++++++----------
|
|
1 file changed, 15 insertions(+), 10 deletions(-)
|
|
|
|
diff --git a/libdm/libdm-stats.c b/libdm/libdm-stats.c
|
|
index c1b1cc466..cbcbb6754 100644
|
|
--- a/libdm/libdm-stats.c
|
|
+++ b/libdm/libdm-stats.c
|
|
@@ -1859,7 +1859,8 @@ bad:
|
|
static size_t _stats_group_tag_len(const struct dm_stats *dms,
|
|
dm_bitset_t regions)
|
|
{
|
|
- int64_t i, j, next, nr_regions = 0;
|
|
+ int i, j, next;
|
|
+ int64_t nr_regions = 0;
|
|
size_t buflen = 0, id_len = 0;
|
|
|
|
/* check region ids and find last set bit */
|
|
@@ -2124,7 +2125,7 @@ out:
|
|
static void _stats_clear_group_regions(struct dm_stats *dms, uint64_t group_id)
|
|
{
|
|
struct dm_stats_group *group;
|
|
- uint64_t i;
|
|
+ int i;
|
|
|
|
group = &dms->groups[group_id];
|
|
for (i = dm_bit_get_first(group->regions);
|
|
@@ -2499,7 +2500,7 @@ void dm_stats_destroy(struct dm_stats *dms)
|
|
* i is a variable of type int that holds the current area_id.
|
|
*/
|
|
#define _foreach_region_area(dms, rid, i) \
|
|
-for ((i) = 0; (i) < _nr_areas_region(&dms->regions[(rid)]); (i)++) \
|
|
+for ((i) = 0; (int)(i) < (int)_nr_areas_region(&dms->regions[(rid)]); (i)++) \
|
|
|
|
/*
|
|
* Walk each region that is a member of group_id gid.
|
|
@@ -2507,7 +2508,7 @@ for ((i) = 0; (i) < _nr_areas_region(&dms->regions[(rid)]); (i)++) \
|
|
*/
|
|
#define _foreach_group_region(dms, gid, i) \
|
|
for ((i) = dm_bit_get_first((dms)->groups[(gid)].regions); \
|
|
- (i) != DM_STATS_GROUP_NOT_PRESENT; \
|
|
+ (int)(i) != (int)DM_STATS_GROUP_NOT_PRESENT; \
|
|
(i) = dm_bit_get_next((dms)->groups[(gid)].regions, (i))) \
|
|
|
|
/*
|
|
@@ -2562,8 +2563,8 @@ uint64_t dm_stats_get_counter(const struct dm_stats *dms,
|
|
dm_stats_counter_t counter,
|
|
uint64_t region_id, uint64_t area_id)
|
|
{
|
|
- uint64_t i, j, sum = 0; /* aggregation */
|
|
- int sum_regions = 0;
|
|
+ uint64_t sum = 0; /* aggregation */
|
|
+ int i, j, sum_regions = 0;
|
|
struct dm_stats_region *region;
|
|
struct dm_stats_counters *area;
|
|
|
|
@@ -3129,7 +3130,7 @@ int dm_stats_get_region_start(const struct dm_stats *dms, uint64_t *start,
|
|
int dm_stats_get_region_len(const struct dm_stats *dms, uint64_t *len,
|
|
uint64_t region_id)
|
|
{
|
|
- uint64_t i;
|
|
+ int i;
|
|
if (!dms || !dms->regions)
|
|
return_0;
|
|
|
|
@@ -3970,11 +3971,15 @@ static int _stats_create_group(struct dm_stats *dms, dm_bitset_t regions,
|
|
const char *alias, uint64_t *group_id)
|
|
{
|
|
struct dm_stats_group *group;
|
|
- *group_id = dm_bit_get_first(regions);
|
|
+ int i = dm_bit_get_first(regions);
|
|
|
|
- /* group has no regions? */
|
|
- if (*group_id == DM_STATS_GROUP_NOT_PRESENT)
|
|
+ if (i < 0) {
|
|
+ /* group has no regions? */
|
|
+ *group_id = DM_STATS_GROUP_NOT_PRESENT;
|
|
return_0;
|
|
+ }
|
|
+
|
|
+ *group_id = (uint64_t)i;
|
|
|
|
group = &dms->groups[*group_id];
|
|
|
|
--
|
|
2.51.0
|
|
|