mirror of
https://github.com/torvalds/linux.git
synced 2026-09-26 01:52:03 +02:00
dm-pcache: validate geometry fields from on-disk cache_info
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: 1d57628ff9 ("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>
This commit is contained in:
parent
90c990a684
commit
32d1809da3
|
|
@ -251,6 +251,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:
|
||||
|
|
@ -266,6 +273,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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user