]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Fix nasty use after free bug revealed by last munmap fix.
authorJeremy Fitzhardinge <jeremy@valgrind.org>
Mon, 22 Dec 2003 10:42:59 +0000 (10:42 +0000)
committerJeremy Fitzhardinge <jeremy@valgrind.org>
Mon, 22 Dec 2003 10:42:59 +0000 (10:42 +0000)
Unexport split_segment; it isn't needed elsewhere.
(Something still wrong with munmap.)

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2143

coregrind/vg_include.h
coregrind/vg_memory.c
coregrind/vg_symtab2.c

index 58788269cef212a3465ae72a06ddee442659235a..0ce9b13748cfd248033062ee76123970edce0b71 100644 (file)
@@ -1580,7 +1580,6 @@ extern Addr VG_(find_map_space)(Addr base, UInt len, Bool for_client);
 
 extern Segment *VG_(find_segment)(Addr a);
 extern Segment *VG_(next_segment)(Segment *);
-extern Segment *VG_(split_segment)(Addr a);
 
 extern Bool     VG_(seg_contains)(const Segment *s, Addr ptr, UInt size);
 extern Bool     VG_(seg_overlaps)(const Segment *s, Addr ptr, UInt size);
index 3a50975d80bc629f8058fe2d6db525afbd234a48..c8b42baabefab1b0aa13c588d4328c5acbbb55cd 100644 (file)
@@ -142,6 +142,9 @@ Segment *VG_(split_segment)(Addr a)
    ns->offset += delta;
    ns->len -= delta;
 
+   if (s->filename != NULL)
+      ns->filename = VG_(arena_strdup)(VG_AR_CORE, s->filename);
+
    if (ns->symtab != NULL)
       VG_(symtab_incref)(ns->symtab);
 
@@ -156,17 +159,19 @@ void VG_(unmap_range)(Addr addr, UInt len)
 {
    Segment *s;
    Segment *next;
-   static const Bool debug = False || mem_debug;
-   Addr end = addr+len;
+   static const Bool debug = True || mem_debug;
+   Addr end;
 
    if (len == 0)
       return;
 
+   len = PGROUNDUP(len);
+   vg_assert(addr == PGROUNDDN(addr));
+
    if (debug)
       VG_(printf)("unmap_range(%p, %d)\n", addr, len);
 
-   len = PGROUNDUP(addr+len)-PGROUNDDN(addr);
-   addr = PGROUNDDN(addr);
+   end = addr+len;
 
    /* Everything must be page-aligned */
    vg_assert((addr & (VKI_BYTES_PER_PAGE-1)) == 0);
@@ -182,7 +187,7 @@ void VG_(unmap_range)(Addr addr, UInt len)
 
       if (debug)
         VG_(printf)("unmap: addr=%p-%p s=%p ->addr=%p-%p len=%d\n",
-                    addr, addr+len, s, s->addr, s->addr+s->len, s->len);
+                    addr, end, s, s->addr, seg_end, s->len);
 
       if (!VG_(seg_overlaps)(s, addr, len)) {
         if (debug)
@@ -217,12 +222,14 @@ void VG_(unmap_range)(Addr addr, UInt len)
         */
         Int delta = (addr+len) - s->addr;
 
+        if (debug)
+           VG_(printf)("  case 3: s->addr=%p s->len=%d delta=%d\n", s->addr, s->len, delta);
+
         s->addr += delta;
         s->offset += delta;
         s->len -= delta;
 
-        if (debug)
-           VG_(printf)("  case 3: s->addr=%p s->len=%d delta=%d\n", s->addr, s->len, delta);
+        vg_assert(s->len != 0);
       } else if (addr > s->addr && end < seg_end) {
         /* [addr, addr+len) is contained within a single segment
            -> split segment into 3, delete middle portion
@@ -245,8 +252,8 @@ void VG_(unmap_range)(Addr addr, UInt len)
    }
 }
 
-/* If possible, merge segment with its neighbours - some segments,
-   including s, may be destroyed in the process */
+/* Return true if two segments are adjacent and mergable (s1 is
+   assumed to have a lower ->addr than s2) */
 static inline Bool neighbours(Segment *s1, Segment *s2)
 {
    if (s1->addr+s1->len != s2->addr)
@@ -273,8 +280,8 @@ static inline Bool neighbours(Segment *s1, Segment *s2)
    return True;
 }
 
-/* Merge segments in the address range if they're adjacent and
-   compatible */
+/* If possible, merge segment with its neighbours - some segments,
+   including s, may be destroyed in the process */
 static void merge_segments(Addr a, UInt len)
 {
    Segment *s;
index bb0c8473f8444bfe36978de28c8760c60547e711..a6e6bc955cd55b69829e55348cc27971634f597c 100644 (file)
@@ -1208,8 +1208,7 @@ SegInfo *VG_(read_seg_symbols) ( Segment *seg )
    si->start    = seg->addr;
    si->size     = seg->len;
    si->foffset  = seg->offset;
-   si->filename = VG_(arena_malloc)(VG_AR_SYMTAB, 1 + VG_(strlen)(seg->filename));
-   VG_(strcpy)(si->filename, seg->filename);
+   si->filename = VG_(arena_strdup)(VG_AR_SYMTAB, seg->filename);
 
    si->ref = 1;