lvm2/0025-libdm-stats-fix-type-mismatch-in-bit-operations.patch
Marian Csontos 275cf34782 Update lvm2 to upstream version 2.03.33
Resolves: RHEL-106257
2025-09-29 18:15:33 +02:00

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