[PATCH v2 05/11] dm-pcache: reject a kset that overruns its segment
Bryam Vargas via B4 Relay <[email protected]> Fri, 17 Jul 2026 06:26:58 -0500
| Newsgroups | dev.linux.lists.dm-devel,org.kernel.feeds.b4-sent,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
From: Bryam Vargas <[email protected]> cache_replay(), the writeback worker and the GC worker read a kset of get_kset_onmedia_size() bytes and advance the position by it. A forged key_num makes that size exceed the segment's remaining space, so the advance walks past the segment and trips the cache_pos_advance() BUG_ON. Reject a kset whose on-media size exceeds cache_seg_remain() before use. Fixes: 1d57628ff95b ("dm-pcache: add persistent cache target in device-mapper") Cc: [email protected] Signed-off-by: Bryam Vargas <[email protected]> --- drivers/md/dm-pcache/cache_gc.c | 5 +++++ drivers/md/dm-pcache/cache_key.c | 5 +++++ drivers/md/dm-pcache/cache_writeback.c | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/drivers/md/dm-pcache/cache_gc.c b/drivers/md/dm-pcache/cache_gc.c index 1ed513745023..c483c7a3afaf 100644 --- a/drivers/md/dm-pcache/cache_gc.c +++ b/drivers/md/dm-pcache/cache_gc.c @@ -146,6 +146,11 @@ void pcache_cache_gc_fn(struct work_struct *work) continue; } + if (get_kset_onmedia_size(kset_onmedia) > cache_seg_remain(&key_tail)) { + atomic_inc(&cache->gc_errors); + return; + } + for (i = 0; i < kset_onmedia->key_num; i++) { struct pcache_cache_key key_tmp = { 0 }; diff --git a/drivers/md/dm-pcache/cache_key.c b/drivers/md/dm-pcache/cache_key.c index f4459b2e1b3b..d00497f9e462 100644 --- a/drivers/md/dm-pcache/cache_key.c +++ b/drivers/md/dm-pcache/cache_key.c @@ -818,6 +818,11 @@ int cache_replay(struct pcache_cache *cache) } /* Replay the kset and check for errors. */ + if (get_kset_onmedia_size(kset_onmedia) > cache_seg_remain(pos)) { + ret = -EIO; + goto out; + } + ret = kset_replay(cache, kset_onmedia); if (ret) goto out; diff --git a/drivers/md/dm-pcache/cache_writeback.c b/drivers/md/dm-pcache/cache_writeback.c index 34c34b448e04..7a85a9aed18e 100644 --- a/drivers/md/dm-pcache/cache_writeback.c +++ b/drivers/md/dm-pcache/cache_writeback.c @@ -261,6 +261,11 @@ void cache_writeback_fn(struct work_struct *work) goto queue_work; } + if (get_kset_onmedia_size(kset_onmedia) > cache_seg_remain(&dirty_tail)) { + atomic_inc(&cache->writeback_errors); + goto unlock; + } + ret = cache_kset_insert_tree(cache, kset_onmedia); if (ret) { atomic_inc(&cache->writeback_errors); -- 2.43.0