]> sourceware.org Git - lvm2.git/commitdiff
Fix access to released memory
authorZdenek Kabelac <zkabelac@redhat.com>
Tue, 29 Mar 2011 21:34:18 +0000 (21:34 +0000)
committerZdenek Kabelac <zkabelac@redhat.com>
Tue, 29 Mar 2011 21:34:18 +0000 (21:34 +0000)
Invalid primary_vginfo was supposed to move all its lvmcache_infos to
orphan_vginfo - however it has called _drop_vginfo() inside the loop
that released primary_vginfo itself - thus made the loop using released
memory.

Use _vginfo_detach_info() instead and call _drop_vginfo after
th loop is finished.

Valgrind trace it should fix:

Invalid read of size 8
   at 0x41E960: _lvmcache_update_vgname (lvmcache.c:1229)
   by 0x41EF86: lvmcache_update_vgname_and_id (lvmcache.c:1360)
   by 0x441393: _text_read (text_label.c:329)
   by 0x442221: label_read (label.c:289)
   by 0x41CF92: lvmcache_label_scan (lvmcache.c:635)
   by 0x45B303: _vg_read_by_vgid (metadata.c:3342)
   by 0x45B4A6: lv_from_lvid (metadata.c:3381)
   by 0x41B555: lv_activation_filter (activate.c:1346)
   by 0x415868: do_activate_lv (lvm-functions.c:343)
   by 0x415E8C: do_lock_lv (lvm-functions.c:532)
   by 0x40FD5F: do_command (clvmd-command.c:120)
   by 0x413D7B: process_local_command (clvmd.c:1686)
 Address 0x63eba10 is 16 bytes inside a block of size 160 free'd
   at 0x4C2756E: free (vg_replace_malloc.c:366)
   by 0x41DE70: _free_vginfo (lvmcache.c:980)
   by 0x41DEDA: _drop_vginfo (lvmcache.c:998)
   by 0x41E854: _lvmcache_update_vgname (lvmcache.c:1238)
   by 0x41EF86: lvmcache_update_vgname_and_id (lvmcache.c:1360)
   by 0x441393: _text_read (text_label.c:329)
   by 0x442221: label_read (label.c:289)
   by 0x41CF92: lvmcache_label_scan (lvmcache.c:635)
   by 0x45B303: _vg_read_by_vgid (metadata.c:3342)
   by 0x45B4A6: lv_from_lvid (metadata.c:3381)
   by 0x41B555: lv_activation_filter (activate.c:1346)
   by 0x415868: do_activate_lv (lvm-functions.c:343)

problematic line:
dm_list_iterate_items_safe(info2, info3, &primary_vginfo->infos)

WHATS_NEW
lib/cache/lvmcache.c

index cfd584430c5da924c99149b699c2e2239d17f9b3..b7c7622e3ba7cf8b867279591aa1d2da93db7211 100644 (file)
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
 Version 2.02.85 - 
 ===================================
+  Fix lvmcache_info transfer to orphan_vginfo in _lvmcache_update_vgname().
   Fix -Wold-style-definition gcc warnings.
   Fixes for lvconvert (including --repair) of temporary mirror stacks.
   Mitigate annoying error warning from device is usable check if run as non-root.
index 4e2e15812c2636225aa2bf0dba0858d0a95e5ef4..ee7d278f3b51030c481c60bbc3c4aae61abfd8d6 100644 (file)
@@ -1107,17 +1107,17 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
                 * Otherwise we risk bogus warnings of duplicate VGs.
                 */
                while ((primary_vginfo = vginfo_from_vgname(vgname, NULL)) &&
-                      _scanning_in_progress && _vginfo_is_invalid(primary_vginfo))
+                      _scanning_in_progress && _vginfo_is_invalid(primary_vginfo)) {
+                       orphan_vginfo = vginfo_from_vgname(primary_vginfo->fmt->orphan_vg_name, NULL);
+                       if (!orphan_vginfo) {
+                               log_error(INTERNAL_ERROR "Orphan vginfo %s lost from cache.",
+                                         primary_vginfo->fmt->orphan_vg_name);
+                               dm_free(vginfo->vgname);
+                               dm_free(vginfo);
+                               return 0;
+                       }
                        dm_list_iterate_items_safe(info2, info3, &primary_vginfo->infos) {
-                               orphan_vginfo = vginfo_from_vgname(primary_vginfo->fmt->orphan_vg_name, NULL);
-                               if (!orphan_vginfo) {
-                                       log_error(INTERNAL_ERROR "Orphan vginfo %s lost from cache.",
-                                                 primary_vginfo->fmt->orphan_vg_name);
-                                       dm_free(vginfo->vgname);
-                                       dm_free(vginfo);
-                                       return 0;
-                               }
-                               _drop_vginfo(info2, primary_vginfo);    
+                               _vginfo_detach_info(info2);
                                _vginfo_attach_info(orphan_vginfo, info2);
                                if (info2->mdas.n)
                                        sprintf(mdabuf, " with %u mdas",
@@ -1129,6 +1129,10 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
                                          vgname, orphan_vginfo->vgid[0] ? " (" : "",
                                          orphan_vginfo->vgid[0] ? orphan_vginfo->vgid : "",
                                          orphan_vginfo->vgid[0] ? ")" : "", mdabuf);
+                       }
+
+                       if (!_drop_vginfo(NULL, primary_vginfo))
+                               return_0;
                }
 
                if (!_insert_vginfo(vginfo, vgid, vgstatus, creation_host,
This page took 0.0504829999999999 seconds and 5 git commands to generate.