linker: initially reserved memory as PROT_NONE
When the dynamic linker loads a shared library into memory, it initially allocates a chunk of memory. The memory is then carved into smaller chunks for each LOAD region, and appropriate memory protections applied. Modify the initial memory allocation so that the pages are mapped as PROT_NONE, rather than PROT_READ / PROT_EXEC. This ensures that gaps between LOAD regions are not inadvertantly readable / executable. (Long term, we should munmap() these gaps entirely) Change-Id: If128a203ccc6fe12dcbbd2bfe0cf13a2045675af
This commit is contained in:
parent
adb6989786
commit
6625986f3a
@ -815,16 +815,15 @@ get_lib_extents(int fd, const char *name, void *__hdr, unsigned *total_sz)
|
|||||||
return (unsigned)req_base;
|
return (unsigned)req_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* alloc_mem_region
|
/* reserve_mem_region
|
||||||
*
|
*
|
||||||
* This function reserves a chunk of memory to be used for mapping in
|
* This function reserves a chunk of memory to be used for mapping in
|
||||||
* the shared library. We reserve the entire memory region here, and
|
* a prelinked shared library. We reserve the entire memory region here, and
|
||||||
* then the rest of the linker will relocate the individual loadable
|
* then the rest of the linker will relocate the individual loadable
|
||||||
* segments into the correct locations within this memory range.
|
* segments into the correct locations within this memory range.
|
||||||
*
|
*
|
||||||
* Args:
|
* Args:
|
||||||
* si->base: The requested base of the allocation. If 0, a sane one will be
|
* si->base: The requested base of the allocation.
|
||||||
* chosen in the range LIBBASE <= base < LIBLAST.
|
|
||||||
* si->size: The size of the allocation.
|
* si->size: The size of the allocation.
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
@ -834,7 +833,7 @@ get_lib_extents(int fd, const char *name, void *__hdr, unsigned *total_sz)
|
|||||||
|
|
||||||
static int reserve_mem_region(soinfo *si)
|
static int reserve_mem_region(soinfo *si)
|
||||||
{
|
{
|
||||||
void *base = mmap((void *)si->base, si->size, PROT_READ | PROT_EXEC,
|
void *base = mmap((void *)si->base, si->size, PROT_NONE,
|
||||||
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||||
if (base == MAP_FAILED) {
|
if (base == MAP_FAILED) {
|
||||||
DL_ERR("%5d can NOT map (%sprelinked) library '%s' at 0x%08x "
|
DL_ERR("%5d can NOT map (%sprelinked) library '%s' at 0x%08x "
|
||||||
@ -852,8 +851,7 @@ static int reserve_mem_region(soinfo *si)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int alloc_mem_region(soinfo *si)
|
||||||
alloc_mem_region(soinfo *si)
|
|
||||||
{
|
{
|
||||||
if (si->base) {
|
if (si->base) {
|
||||||
/* Attempt to mmap a prelinked library. */
|
/* Attempt to mmap a prelinked library. */
|
||||||
@ -864,7 +862,7 @@ alloc_mem_region(soinfo *si)
|
|||||||
allocator.
|
allocator.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void *base = mmap(NULL, si->size, PROT_READ | PROT_EXEC,
|
void *base = mmap(NULL, si->size, PROT_NONE,
|
||||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||||
if (base == MAP_FAILED) {
|
if (base == MAP_FAILED) {
|
||||||
DL_ERR("%5d mmap of library '%s' failed: %d (%s)\n",
|
DL_ERR("%5d mmap of library '%s' failed: %d (%s)\n",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user