Re: [PATCH 2/3] dm-pcache: validate geometry fields from on-disk cache_info

Zheng Gu <[email protected]>
Newsgroups dev.linux.lists.dm-devel,org.kernel.vger.linux-kernel
Message-ID <CADSj-Vo3oHat5JxDLZjeQv7xCroSGC06gkcKxQyH6Lq3EuaKnw@mail.gmail.com>
On Fri, Jun 19, 2026 at 7:44 PM Bryam Vargas via B4 Relay
<[email protected]> wrote:
>
> From: Bryam Vargas <[email protected]>
>
> cache_segs_init() iterates cache_info->n_segs times indexing
> cache->segments[], which is sized to the cache device geometry, and
> get_seg_id() takes each segment id from the on-media cache_info and the
> per-segment next_seg link. Both come from cache device metadata that is
> only CRC-protected with a fixed public seed, so whoever supplies the
> cache device on a table load (CAP_SYS_ADMIN) controls them: an oversized
> n_segs or an out-of-range id drives an out-of-bounds access of
> cache->segments[] and a wild CACHE_DEV_SEGMENT() pointer into the device
> mapping -- an out-of-bounds read and write from on-disk data.
>
> Reject an n_segs that exceeds the device segment count and a segment id
> that is out of range before either is used. Valid metadata is unaffected.
>
> 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.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
>
> diff --git a/drivers/md/dm-pcache/cache.c b/drivers/md/dm-pcache/cache.c
> index e6a2f4460f6e..08decbebd238 100644
> --- a/drivers/md/dm-pcache/cache.c
> +++ b/drivers/md/dm-pcache/cache.c
> @@ -250,6 +250,13 @@ static int get_seg_id(struct pcache_cache *cache,
>                 } else {
>                         *seg_id = cache->cache_info.seg_id;
>                 }
> +
> +               if (*seg_id >= cache_dev->seg_num) {
> +                       pcache_dev_err(pcache, "invalid segment id %u from cache device (seg_num %u)\n",
> +                                      *seg_id, cache_dev->seg_num);
> +                       ret = -EIO;
> +                       goto err;
> +               }
>         }
>         return 0;
>  err:
> @@ -265,6 +272,13 @@ static int cache_segs_init(struct pcache_cache *cache)
>         int ret;
>         u32 i;
>
> +       if (cache_info->n_segs > cache->cache_dev->seg_num) {
> +               pcache_dev_err(CACHE_TO_PCACHE(cache),
> +                              "cache_info n_segs %u exceeds cache device segments %u\n",
> +                              cache_info->n_segs, cache->cache_dev->seg_num);
> +               return -EIO;
> +       }
> +
>         for (i = 0; i < cache_info->n_segs; i++) {
>                 ret = get_seg_id(cache, prev_cache_seg, new_cache, &seg_id);
>                 if (ret)
>
> --
> 2.43.0
>
>

Reviewed-by:  Zheng Gu <[email protected]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.