From f8763a02a1620844ed7326ea88ea8181e8b58aad Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Mon, 6 Jul 2026 15:43:50 +0200 Subject: [PATCH] generator: Protect against invalid values __builtin_clz() produces undefined behavior for argument equal 0. Implement proper handing of such a case. Signed-off-by: Robert Baldyga --- src/ocf_lru.c | 5 ++++- src/utils/utils_generator.c | 24 ++++++++++++++++++++---- src/utils/utils_generator.h | 3 ++- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/ocf_lru.c b/src/ocf_lru.c index 7a0d959e4..af35aa2a8 100644 --- a/src/ocf_lru.c +++ b/src/ocf_lru.c @@ -1031,6 +1031,7 @@ static int ocf_lru_populate_handle(ocf_parallelize_t parallelize, uint32_t partial_chunk_lines = 0; uint32_t num_chunks, chunk_idx, chunk_lines; uint32_t ci, j; + int result; /* Check if this shard has a partial last chunk */ if (remainder > (uint32_t)shard_id * OCF_LRU_CHUNK_SIZE) { @@ -1044,7 +1045,9 @@ static int ocf_lru_populate_handle(ocf_parallelize_t parallelize, if (num_chunks == 0) return 0; - ocf_generator_bisect_init(&generator, num_chunks, 0); + result = ocf_generator_bisect_init(&generator, num_chunks, 0); + if (result) + return result; list = ocf_lru_get_list(&cache->free, shard_id, true); diff --git a/src/utils/utils_generator.c b/src/utils/utils_generator.c index 47ab7e653..e04c80291 100644 --- a/src/utils/utils_generator.c +++ b/src/utils/utils_generator.c @@ -1,5 +1,6 @@ /* * Copyright(c) 2022 Intel Corporation + * Copyright(c) 2026 Unvertical * SPDX-License-Identifier: BSD-3-Clause */ @@ -29,20 +30,32 @@ static inline uint32_t bitreverse32(register uint32_t x) * returned by the generator is limit - 1) * @param[in] offset Offset at which generator should start * - * @return Reversed value + * @return Zero when success, otherwise an error */ -void ocf_generator_bisect_init( +int ocf_generator_bisect_init( struct ocf_generator_bisect_state *generator, uint32_t limit, uint32_t offset) { unsigned clz; uint32_t maplen; - clz = __builtin_clz(limit - 1); - maplen = 1 << (32 - clz); + if (limit == 0) + return -OCF_ERR_INVAL; + + if (offset >= limit) + return -OCF_ERR_INVAL; + + if (limit > 1) { + clz = __builtin_clz(limit - 1); + maplen = 1 << (32 - clz); + } else { + maplen = 1; + } generator->curr = (uint64_t)offset * maplen / limit; generator->limit = limit; + + return 0; } /** @@ -180,6 +193,9 @@ uint32_t ocf_generator_bisect_next( uint32_t maplen; uint32_t value; + if (generator->limit == 1) + return 0; + clz = __builtin_clz(generator->limit - 1); maplen = 1 << (32 - clz); diff --git a/src/utils/utils_generator.h b/src/utils/utils_generator.h index 068602d0b..df8cb1ba1 100644 --- a/src/utils/utils_generator.h +++ b/src/utils/utils_generator.h @@ -1,5 +1,6 @@ /* * Copyright(c) 2022 Intel Corporation + * Copyright(c) 2026 Unvertical * SPDX-License-Identifier: BSD-3-Clause */ @@ -13,7 +14,7 @@ struct ocf_generator_bisect_state { uint32_t limit; }; -void ocf_generator_bisect_init( +int ocf_generator_bisect_init( struct ocf_generator_bisect_state *generator, uint32_t limit, uint32_t offset);