diff options
| author | Bryam Vargas <hexlabsecurity@proton.me> | 2026-07-17 06:26:59 -0500 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-09-07 17:22:57 +0200 |
| commit | 663ee2f3824a505b983162de44134e789f8230da (patch) | |
| tree | b3b35b43147d3843eccdb6ae2791ef1b106e7a18 | |
| parent | 2cd9776fe3f2d88ec22c36d3c8ba09fbf9d5500c (diff) | |
| download | linux-663ee2f3824a505b983162de44134e789f8230da.tar.gz linux-663ee2f3824a505b983162de44134e789f8230da.zip | |
dm-pcache: detect a cycle in the last-kset chain during replay
commit 16c3b3a326e70f246a605b3dc27b7f83ba4743e3 upstream.
cache_replay() follows the on-media last-kset chain by next_cache_seg_id
with no cond_resched(). A forged chain that points back into a segment it
has already visited makes the replay loop follow it forever.
Cap the last-kset hops at cache->n_segs; a valid chain visits each segment
at most once.
Fixes: 1d57628ff95b ("dm-pcache: add persistent cache target in device-mapper")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
| -rw-r--r-- | drivers/md/dm-pcache/cache_key.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/md/dm-pcache/cache_key.c b/drivers/md/dm-pcache/cache_key.c index def81b74a181..c855301fd6d8 100644 --- a/drivers/md/dm-pcache/cache_key.c +++ b/drivers/md/dm-pcache/cache_key.c @@ -762,7 +762,7 @@ int cache_replay(struct pcache_cache *cache) struct pcache_cache_pos pos_tail; struct pcache_cache_pos *pos; struct pcache_cache_kset_onmedia *kset_onmedia; - u32 to_copy, count = 0; + u32 to_copy, count = 0, last_hops = 0; int ret = 0; kset_onmedia = kzalloc(PCACHE_KSET_ONMEDIA_SIZE_MAX, GFP_KERNEL); @@ -797,6 +797,11 @@ int cache_replay(struct pcache_cache *cache) pcache_dev_debug(pcache, "last kset replay, next: %u\n", kset_onmedia->next_cache_seg_id); + if (++last_hops > cache->n_segs) { + ret = -EIO; + goto out; + } + next_seg = &cache->segments[kset_onmedia->next_cache_seg_id]; pos->cache_seg = next_seg; |
