Bug 1400146 - Gracefully handle the allocator not being initialized in isalloc_validate. r=njn

isalloc_validate is the function behind malloc_usable_size. If for some
reason malloc_usable_size is called before mozjemalloc is initialized,
this can lead to an unexpected crash.

The chance of this actually happening is rather slim on Linux
and Windows (although still possible), and impossible on Mac, due to the
fact the earlier something can end up calling it is after the
mozjemalloc zone is registered, which happens after initialization.

... except with bug 1399921, which reorders that initialization, and
puts the zone registration first. There's then a slim chance for the
zone allocator to call into zone_size, which calls malloc_usable_size,
to determine whether a pointer allocated by some other zone belongs to
mozjemalloc's.

And it turns out that does happen, during the startup of the
plugin-container process on OSX 10.10 (but not more recent versions).

--HG--
extra : rebase_source : 331d093b03add7b2c2ce440593f5aeccaaf4dd1f
This commit is contained in:
Mike Hommey 2017-09-15 15:13:52 +09:00
Родитель 5e500229a1
Коммит 50182c9f53
1 изменённых файлов: 30 добавлений и 25 удалений

Просмотреть файл

@ -3510,36 +3510,41 @@ arena_salloc(const void *ptr)
* + Check that ptr lies within a mapped chunk.
*/
static inline size_t
isalloc_validate(const void *ptr)
isalloc_validate(const void* ptr)
{
arena_chunk_t *chunk;
/* If the allocator is not initialized, the pointer can't belong to it. */
if (malloc_initialized == false) {
return 0;
}
chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
if (!chunk)
return (0);
arena_chunk_t* chunk = (arena_chunk_t*)CHUNK_ADDR2BASE(ptr);
if (!chunk) {
return 0;
}
if (!malloc_rtree_get(chunk_rtree, (uintptr_t)chunk))
return (0);
if (!malloc_rtree_get(chunk_rtree, (uintptr_t)chunk)) {
return 0;
}
if (chunk != ptr) {
MOZ_DIAGNOSTIC_ASSERT(chunk->arena->magic == ARENA_MAGIC);
return (arena_salloc(ptr));
} else {
size_t ret;
extent_node_t *node;
extent_node_t key;
if (chunk != ptr) {
MOZ_DIAGNOSTIC_ASSERT(chunk->arena->magic == ARENA_MAGIC);
return arena_salloc(ptr);
} else {
size_t ret;
extent_node_t* node;
extent_node_t key;
/* Chunk. */
key.addr = (void *)chunk;
malloc_mutex_lock(&huge_mtx);
node = extent_tree_ad_search(&huge, &key);
if (node)
ret = node->size;
else
ret = 0;
malloc_mutex_unlock(&huge_mtx);
return (ret);
}
/* Chunk. */
key.addr = (void*)chunk;
malloc_mutex_lock(&huge_mtx);
node = extent_tree_ad_search(&huge, &key);
if (node)
ret = node->size;
else
ret = 0;
malloc_mutex_unlock(&huge_mtx);
return ret;
}
}
static inline size_t