mirror of
https://github.com/rui314/mold.git
synced 2024-10-04 16:48:04 +03:00
[ELF] Protect the last page of a RELRO segment
PT_GNU_RELRO works on page granularity. We always align the begining of a RELRO segment to a page boundary, but the end was not. Since the runtime conservatively align _down_ it to a page boundary, the last page weren't be marked as read-only. This patch makes the size of a RELRO always a multiple of the page size.
This commit is contained in:
parent
b2ef045c03
commit
0a0f9b3ad5
@ -255,6 +255,12 @@ std::vector<ElfPhdr<E>> create_phdr(Context<E> &ctx) {
|
||||
i++;
|
||||
while (i < ctx.chunks.size() && is_relro(ctx, ctx.chunks[i]))
|
||||
append(ctx.chunks[i++]);
|
||||
|
||||
// RELRO works on page granularity, so align it up to the next
|
||||
// page boundary.
|
||||
assert(i == ctx.chunks.size() ||
|
||||
ctx.chunks[i]->shdr.sh_addr % ctx.page_size == 0);
|
||||
vec.back().p_memsz = align_to(vec.back().p_memsz, ctx.page_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,11 +11,32 @@ t=out/test/elf/$testname
|
||||
mkdir -p $t
|
||||
|
||||
cat <<EOF | $CC -o $t/a.o -c -xc -fno-PIE -
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern const char readonly[100];
|
||||
extern char readwrite[100];
|
||||
|
||||
static int segv = 0;
|
||||
static jmp_buf buf;
|
||||
|
||||
void handler(int sig) {
|
||||
segv = 1;
|
||||
longjmp(buf, 1);
|
||||
}
|
||||
|
||||
int main() {
|
||||
return readonly[0] + readwrite[0];
|
||||
signal(SIGSEGV, handler);
|
||||
|
||||
readwrite[0] = 5;
|
||||
int x = segv;
|
||||
|
||||
if (setjmp(buf) == 0)
|
||||
*(char *)(readonly) = 5;
|
||||
int y = segv;
|
||||
|
||||
printf("sigsegv %d %d\n", x, y);
|
||||
}
|
||||
EOF
|
||||
|
||||
@ -24,10 +45,7 @@ const char readonly[100] = "abc";
|
||||
char readwrite[100] = "abc";
|
||||
EOF
|
||||
|
||||
$CC -B. $t/a.o $t/b.so -o $t/exe
|
||||
readelf -a $t/exe > $t/log
|
||||
|
||||
grep -Pqz '(?s)\[(\d+)\] .dynbss.rel.ro .* \1 readonly' $t/log
|
||||
grep -Pqz '(?s)\[(\d+)\] .dynbss .* \1 readwrite' $t/log
|
||||
$CC -B. $t/a.o $t/b.so -o $t/exe -no-pie
|
||||
$t/exe | grep -q '^sigsegv 0 1$'
|
||||
|
||||
echo OK
|
||||
|
Loading…
Reference in New Issue
Block a user