From 142d2e87406e1db97ddce8322e49414d74cc3be4 Mon Sep 17 00:00:00 2001 From: Zdenek Kabelac Date: Wed, 30 Mar 2011 12:30:39 +0000 Subject: [PATCH] Fix reading of unitialized memory Could be reached via few of our lvm2 test cases: ==11501== Invalid read of size 8 ==11501== at 0x49B2E0: _area_length (import-extents.c:204) ==11501== by 0x49B40C: _read_linear (import-extents.c:222) ==11501== by 0x49B952: _build_segments (import-extents.c:323) ==11501== by 0x49B9A0: _build_all_segments (import-extents.c:334) ==11501== by 0x49BB4C: import_extents (import-extents.c:364) ==11501== by 0x497655: _format1_vg_read (format1.c:217) ==11501== by 0x47E43E: _vg_read (metadata.c:2901) cut from t-vgcvgbackup-usage.sh -- pvcreate -M1 $(cat DEVICES) vgcreate -M1 -c n $vg $(cat DEVICES) lvcreate -l1 -n $lv1 $vg $dev1 -- Idea of the fix is rather defensive - to allocate one extra element to 'map' array which is then used in _area_length() - where the loop checks, whether next map entry is continuous. By placing there always one extra zero entry - we fix the read of unallocated memory, and we make sure the data would not make a continous block. FIXME: there could be a problem if some special broken lvm1 data would be imported. As the format1 is currently not really used - leave it for future fix and use this small hotfix for now. --- WHATS_NEW | 1 + lib/format1/import-extents.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/WHATS_NEW b/WHATS_NEW index 28dececc3..39c051c78 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.85 - =================================== + Fix reading of unallocated memory in lvm1 format import function. Replace several strncmp() calls with id_equal(). Fix lvmcache_info transfer to orphan_vginfo in _lvmcache_update_vgname(). Fix -Wold-style-definition gcc warnings. diff --git a/lib/format1/import-extents.c b/lib/format1/import-extents.c index 99723eef5..e6c5e33b4 100644 --- a/lib/format1/import-extents.c +++ b/lib/format1/import-extents.c @@ -63,8 +63,12 @@ static struct dm_hash_table *_create_lv_maps(struct dm_pool *mem, goto_bad; lvm->lv = ll->lv; + /* + * Alloc 1 extra element, so the loop in _area_length() and + * _check_stripe() finds the last map member as noncontinuous. + */ if (!(lvm->map = dm_pool_zalloc(mem, sizeof(*lvm->map) - * ll->lv->le_count))) + * (ll->lv->le_count + 1)))) goto_bad; if (!dm_hash_insert(maps, ll->lv->name, lvm)) -- 2.43.5