diff options
author | Rich Felker <dalias@aerifal.cx> | 2017-06-15 12:54:40 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2017-06-15 12:54:40 -0400 |
commit | 1c86c7f5c26dd0569df7afc23ee9866fb3f645dc (patch) | |
tree | 0d512c978c4ced20a1dd2f00d38dd44cc65a06e9 | |
parent | 10800088099ec4c27c1db6c613c8bbf9f76e4057 (diff) | |
download | musl-1c86c7f5c26dd0569df7afc23ee9866fb3f645dc.tar.gz musl-1c86c7f5c26dd0569df7afc23ee9866fb3f645dc.tar.bz2 musl-1c86c7f5c26dd0569df7afc23ee9866fb3f645dc.tar.xz musl-1c86c7f5c26dd0569df7afc23ee9866fb3f645dc.zip |
handle mremap failure in realloc of mmap-serviced allocations
mremap seems to always fail on nommu, and on some non-Linux
implementations of the Linux syscall API, it at least fails to
increase allocation size, and may fail to move (i.e. defragment) the
existing mapping when shrinking it too. instead of failing realloc or
leaving an over-sized allocation that may waste a large amount of
memory, fallback to malloc-memcpy-free if mremap fails.
-rw-r--r-- | src/malloc/malloc.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/src/malloc/malloc.c b/src/malloc/malloc.c index c38c46fe..d5ee4280 100644 --- a/src/malloc/malloc.c +++ b/src/malloc/malloc.c @@ -406,7 +406,7 @@ void *realloc(void *p, size_t n) if (oldlen == newlen) return p; base = __mremap(base, oldlen, newlen, MREMAP_MAYMOVE); if (base == (void *)-1) - return newlen < oldlen ? p : 0; + goto copy_realloc; self = (void *)(base + extra); self->csize = newlen - extra; return CHUNK_TO_MEM(self); @@ -439,6 +439,7 @@ void *realloc(void *p, size_t n) return CHUNK_TO_MEM(self); } +copy_realloc: /* As a last resort, allocate a new chunk and copy to it. */ new = malloc(n-OVERHEAD); if (!new) return 0; |