From: Bryam Vargas <[email protected]>

The tail-kset read in cache_replay(), the writeback worker and the GC
worker bounds its length by PCACHE_SEG_SIZE - seg_off, the raw segment
size rather than the data region. A tail near the segment end reads past
the segment data into the following control area.

Clamp the read to cache_seg_remain(), the data region.

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        | 2 +-
 drivers/md/dm-pcache/cache_key.c       | 2 +-
 drivers/md/dm-pcache/cache_writeback.c | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/md/dm-pcache/cache_gc.c b/drivers/md/dm-pcache/cache_gc.c
index c483c7a3afaf..d551848912b4 100644
--- a/drivers/md/dm-pcache/cache_gc.c
+++ b/drivers/md/dm-pcache/cache_gc.c
@@ -37,7 +37,7 @@ static bool need_gc(struct pcache_cache *cache, struct 
pcache_cache_pos *dirty_t
 
        kset_onmedia = (struct pcache_cache_kset_onmedia 
*)cache->gc_kset_onmedia_buf;
 
-       to_copy = min(PCACHE_KSET_ONMEDIA_SIZE_MAX, PCACHE_SEG_SIZE - 
key_tail->seg_off);
+       to_copy = min(PCACHE_KSET_ONMEDIA_SIZE_MAX, cache_seg_remain(key_tail));
        ret = copy_mc_to_kernel(kset_onmedia, key_addr, to_copy);
        if (ret) {
                pcache_dev_err(pcache, "error to read kset: %d", ret);
diff --git a/drivers/md/dm-pcache/cache_key.c b/drivers/md/dm-pcache/cache_key.c
index 86cc9565ffc7..f3ce319037be 100644
--- a/drivers/md/dm-pcache/cache_key.c
+++ b/drivers/md/dm-pcache/cache_key.c
@@ -794,7 +794,7 @@ int cache_replay(struct pcache_cache *cache)
        __set_bit(pos->cache_seg->cache_seg_id, cache->seg_map);
 
        while (true) {
-               to_copy = min(PCACHE_KSET_ONMEDIA_SIZE_MAX, PCACHE_SEG_SIZE - 
pos->seg_off);
+               to_copy = min(PCACHE_KSET_ONMEDIA_SIZE_MAX, 
cache_seg_remain(pos));
                ret = copy_mc_to_kernel(kset_onmedia, cache_pos_addr(pos), 
to_copy);
                if (ret) {
                        ret = -EIO;
diff --git a/drivers/md/dm-pcache/cache_writeback.c 
b/drivers/md/dm-pcache/cache_writeback.c
index 7a85a9aed18e..c8a4c8110a58 100644
--- a/drivers/md/dm-pcache/cache_writeback.c
+++ b/drivers/md/dm-pcache/cache_writeback.c
@@ -48,7 +48,7 @@ static inline bool is_cache_clean(struct pcache_cache *cache, 
struct pcache_cach
        addr = cache_pos_addr(dirty_tail);
        kset_onmedia = (struct pcache_cache_kset_onmedia 
*)cache->wb_kset_onmedia_buf;
 
-       to_copy = min(PCACHE_KSET_ONMEDIA_SIZE_MAX, PCACHE_SEG_SIZE - 
dirty_tail->seg_off);
+       to_copy = min(PCACHE_KSET_ONMEDIA_SIZE_MAX, 
cache_seg_remain(dirty_tail));
        ret = copy_mc_to_kernel(kset_onmedia, addr, to_copy);
        if (ret) {
                pcache_dev_err(pcache, "error to read kset: %d", ret);

-- 
2.43.0



Reply via email to