!14032  fix CVE-2024-50278

Merge Pull Request from: @ci-robot 
 
PR sync from: Zheng Qixing <zhengqixing@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/37Q5XDWXSUOXH5QO4ZBD72UOQ65VQNOA/ 
Fix CVE-2024-50278.

Ming-Hung Tsai (3):
  dm cache: fix out-of-bounds access to the dirty bitset when resizing
  dm cache: optimize dirty bit checking with find_next_bit when resizing
  dm cache: fix potential out-of-bounds access on the first resume


-- 
2.39.2
 
https://gitee.com/src-openeuler/kernel/issues/IB5AV2 
 
Link:https://gitee.com/openeuler/kernel/pulls/14032 

Reviewed-by: Yu Kuai <yukuai3@huawei.com> 
Reviewed-by: Li Nan <linan122@huawei.com> 
Signed-off-by: Li Nan <linan122@huawei.com> 
diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c
index 4bc453f..55f5cde 100644
--- a/drivers/md/dm-cache-target.c
+++ b/drivers/md/dm-cache-target.c
@@ -2950,19 +2950,19 @@ static dm_cblock_t get_cache_dev_size(struct cache *cache)
 static bool can_resize(struct cache *cache, dm_cblock_t new_size)
 {
 	if (from_cblock(new_size) > from_cblock(cache->cache_size)) {
-		if (cache->sized) {
-			DMERR("%s: unable to extend cache due to missing cache table reload",
-			      cache_device_name(cache));
-			return false;
-		}
+		DMERR("%s: unable to extend cache due to missing cache table reload",
+		      cache_device_name(cache));
+		return false;
 	}
 
 	/*
 	 * We can't drop a dirty block when shrinking the cache.
 	 */
-	while (from_cblock(new_size) < from_cblock(cache->cache_size)) {
-		new_size = to_cblock(from_cblock(new_size) + 1);
-		if (is_dirty(cache, new_size)) {
+	if (cache->loaded_mappings) {
+		new_size = to_cblock(find_next_bit(cache->dirty_bitset,
+						   from_cblock(cache->cache_size),
+						   from_cblock(new_size)));
+		if (new_size != cache->cache_size) {
 			DMERR("%s: unable to shrink cache; cache block %llu is dirty",
 			      cache_device_name(cache),
 			      (unsigned long long) from_cblock(new_size));
@@ -2998,20 +2998,15 @@ static int cache_preresume(struct dm_target *ti)
 	/*
 	 * Check to see if the cache has resized.
 	 */
-	if (!cache->sized) {
-		r = resize_cache_dev(cache, csize);
-		if (r)
-			return r;
-
-		cache->sized = true;
-
-	} else if (csize != cache->cache_size) {
+	if (!cache->sized || csize != cache->cache_size) {
 		if (!can_resize(cache, csize))
 			return -EINVAL;
 
 		r = resize_cache_dev(cache, csize);
 		if (r)
 			return r;
+
+		cache->sized = true;
 	}
 
 	if (!cache->loaded_mappings) {