зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1455662 - Guard against mprotect() failure when manipulating link map r=jchen
MozReview-Commit-ID: 7orhBmf4j5j
This commit is contained in:
Родитель
9b0a00e563
Коммит
624417af1d
|
@ -904,16 +904,28 @@ public:
|
||||||
if (prot == -1 || (start + length) > end)
|
if (prot == -1 || (start + length) > end)
|
||||||
MOZ_CRASH();
|
MOZ_CRASH();
|
||||||
|
|
||||||
if (prot & PROT_WRITE)
|
if (prot & PROT_WRITE) {
|
||||||
|
success = true;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
page = firstPage;
|
page = firstPage;
|
||||||
mprotect(page, length, prot | PROT_WRITE);
|
int ret = mprotect(page, length, prot | PROT_WRITE);
|
||||||
|
success = ret == 0;
|
||||||
|
if (!success) {
|
||||||
|
ERROR("mprotect(%p, %zu, %d) = %d (errno=%d; %s)",
|
||||||
|
page, length, prot | PROT_WRITE, ret,
|
||||||
|
errno, strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsWritable() const {
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
~EnsureWritable()
|
~EnsureWritable()
|
||||||
{
|
{
|
||||||
if (page != MAP_FAILED) {
|
if (success && page != MAP_FAILED) {
|
||||||
mprotect(page, length, prot);
|
mprotect(page, length, prot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -953,6 +965,7 @@ private:
|
||||||
int prot;
|
int prot;
|
||||||
void *page;
|
void *page;
|
||||||
size_t length;
|
size_t length;
|
||||||
|
bool success;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -976,18 +989,28 @@ ElfLoader::DebuggerHelper::Add(ElfLoader::link_map *map)
|
||||||
{
|
{
|
||||||
if (!dbg->r_brk)
|
if (!dbg->r_brk)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dbg->r_state = r_debug::RT_ADD;
|
dbg->r_state = r_debug::RT_ADD;
|
||||||
dbg->r_brk();
|
dbg->r_brk();
|
||||||
map->l_prev = nullptr;
|
|
||||||
map->l_next = dbg->r_map;
|
|
||||||
if (!firstAdded) {
|
if (!firstAdded) {
|
||||||
firstAdded = map;
|
|
||||||
/* When adding a library for the first time, r_map points to data
|
/* When adding a library for the first time, r_map points to data
|
||||||
* handled by the system linker, and that data may be read-only */
|
* handled by the system linker, and that data may be read-only */
|
||||||
EnsureWritable w(&dbg->r_map->l_prev);
|
EnsureWritable w(&dbg->r_map->l_prev);
|
||||||
|
if (!w.IsWritable()) {
|
||||||
|
dbg->r_state = r_debug::RT_CONSISTENT;
|
||||||
|
dbg->r_brk();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
firstAdded = map;
|
||||||
dbg->r_map->l_prev = map;
|
dbg->r_map->l_prev = map;
|
||||||
} else
|
} else
|
||||||
dbg->r_map->l_prev = map;
|
dbg->r_map->l_prev = map;
|
||||||
|
|
||||||
|
map->l_prev = nullptr;
|
||||||
|
map->l_next = dbg->r_map;
|
||||||
|
|
||||||
dbg->r_map = map;
|
dbg->r_map = map;
|
||||||
dbg->r_state = r_debug::RT_CONSISTENT;
|
dbg->r_state = r_debug::RT_CONSISTENT;
|
||||||
dbg->r_brk();
|
dbg->r_brk();
|
||||||
|
@ -998,22 +1021,31 @@ ElfLoader::DebuggerHelper::Remove(ElfLoader::link_map *map)
|
||||||
{
|
{
|
||||||
if (!dbg->r_brk)
|
if (!dbg->r_brk)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dbg->r_state = r_debug::RT_DELETE;
|
dbg->r_state = r_debug::RT_DELETE;
|
||||||
dbg->r_brk();
|
dbg->r_brk();
|
||||||
|
|
||||||
|
if (map == firstAdded) {
|
||||||
|
/* When removing the first added library, its l_next is going to be
|
||||||
|
* data handled by the system linker, and that data may be read-only */
|
||||||
|
EnsureWritable w(&map->l_next->l_prev);
|
||||||
|
if (!w.IsWritable()) {
|
||||||
|
dbg->r_state = r_debug::RT_CONSISTENT;
|
||||||
|
dbg->r_brk();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
firstAdded = map->l_prev;
|
||||||
|
map->l_next->l_prev = map->l_prev;
|
||||||
|
} else if (map->l_next) {
|
||||||
|
map->l_next->l_prev = map->l_prev;
|
||||||
|
}
|
||||||
|
|
||||||
if (dbg->r_map == map)
|
if (dbg->r_map == map)
|
||||||
dbg->r_map = map->l_next;
|
dbg->r_map = map->l_next;
|
||||||
else if (map->l_prev) {
|
else if (map->l_prev) {
|
||||||
map->l_prev->l_next = map->l_next;
|
map->l_prev->l_next = map->l_next;
|
||||||
}
|
}
|
||||||
if (map == firstAdded) {
|
|
||||||
firstAdded = map->l_prev;
|
|
||||||
/* When removing the first added library, its l_next is going to be
|
|
||||||
* data handled by the system linker, and that data may be read-only */
|
|
||||||
EnsureWritable w(&map->l_next->l_prev);
|
|
||||||
map->l_next->l_prev = map->l_prev;
|
|
||||||
} else if (map->l_next) {
|
|
||||||
map->l_next->l_prev = map->l_prev;
|
|
||||||
}
|
|
||||||
dbg->r_state = r_debug::RT_CONSISTENT;
|
dbg->r_state = r_debug::RT_CONSISTENT;
|
||||||
dbg->r_brk();
|
dbg->r_brk();
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче