From: Jeremy Fitzhardinge Date: Mon, 22 Dec 2003 10:42:59 +0000 (+0000) Subject: Fix nasty use after free bug revealed by last munmap fix. X-Git-Tag: svn/VALGRIND_2_1_1~159 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a77797ee87cf8c2dc5df4a778b7de03800a0fb1d;p=thirdparty%2Fvalgrind.git Fix nasty use after free bug revealed by last munmap fix. Unexport split_segment; it isn't needed elsewhere. (Something still wrong with munmap.) git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2143 --- diff --git a/coregrind/vg_include.h b/coregrind/vg_include.h index 58788269ce..0ce9b13748 100644 --- a/coregrind/vg_include.h +++ b/coregrind/vg_include.h @@ -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); diff --git a/coregrind/vg_memory.c b/coregrind/vg_memory.c index 3a50975d80..c8b42baabe 100644 --- a/coregrind/vg_memory.c +++ b/coregrind/vg_memory.c @@ -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; diff --git a/coregrind/vg_symtab2.c b/coregrind/vg_symtab2.c index bb0c8473f8..a6e6bc955c 100644 --- a/coregrind/vg_symtab2.c +++ b/coregrind/vg_symtab2.c @@ -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;