提交 f7d15dcc 编写于 作者: R Rich Felker

treat failure of mprotect in map_library as a fatal load failure

the error will propagate up and be printed to the user at program
start time; at runtime, dlopen will just fail and leave a message for
dlerror.

previously, if mprotect failed, subsequent attempts to perform
relocations would crash the program. this was resulting in an
increasing number of false bug reports on grsec systems where rwx
permission is not possible in cases where users were wrongly
attempting to use non-PIC code in shared libraries. supporting that
usage is in theory possible, but the x86_64 toolchain does not even
support textrels, and the cost of keeping around the necessary
information to handle textrels without rwx permissions is
disproportionate to the benefit (which is essentially just supporting
broken library setups on grsec machines).

also, i unified the error-out code in map_library now that there are 3
places from which munmap might have to be called.
上级 908bed20
......@@ -268,23 +268,20 @@ static void *map_library(int fd, size_t *lenp, unsigned char **basep, size_t *dy
prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
((ph->p_flags&PF_X) ? PROT_EXEC : 0));
if (mmap(base+this_min, this_max-this_min, prot, MAP_PRIVATE|MAP_FIXED, fd, off_start) == MAP_FAILED) {
munmap(map, map_len);
return 0;
}
if (mmap(base+this_min, this_max-this_min, prot, MAP_PRIVATE|MAP_FIXED, fd, off_start) == MAP_FAILED)
goto error;
if (ph->p_memsz > ph->p_filesz) {
size_t brk = (size_t)base+ph->p_vaddr+ph->p_filesz;
size_t pgbrk = brk+PAGE_SIZE-1 & -PAGE_SIZE;
memset((void *)brk, 0, pgbrk-brk & PAGE_SIZE-1);
if (pgbrk-(size_t)base < this_max && mmap((void *)pgbrk, (size_t)base+this_max-pgbrk, prot, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) == MAP_FAILED) {
munmap(map, map_len);
return 0;
}
if (pgbrk-(size_t)base < this_max && mmap((void *)pgbrk, (size_t)base+this_max-pgbrk, prot, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) == MAP_FAILED)
goto error;
}
}
for (i=0; ((size_t *)(base+dyn))[i]; i+=2)
if (((size_t *)(base+dyn))[i]==DT_TEXTREL) {
mprotect(map, map_len, PROT_READ|PROT_WRITE|PROT_EXEC);
if (mprotect(map, map_len, PROT_READ|PROT_WRITE|PROT_EXEC) < 0)
goto error;
break;
}
if (!runtime) reclaim_gaps(base, (void *)((char *)buf + eh->e_phoff),
......@@ -293,6 +290,9 @@ static void *map_library(int fd, size_t *lenp, unsigned char **basep, size_t *dy
*basep = base;
*dynp = dyn;
return map;
error:
munmap(map, map_len);
return 0;
}
static int path_open(const char *name, const char *search, char *buf, size_t buf_size)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册