From 1b1ab744e5c3315dbdccdd125481c3998ec0c5cf Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Thu, 17 Aug 2023 11:54:45 +0900 Subject: [PATCH] Copy RELRO symbols to .copyrel.rel.ro instead of to .copyrel So that readonly data wouldn't become writable by copy relocations. --- elf/input-files.cc | 3 ++- test/elf/copyrel-relro2.sh | 40 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100755 test/elf/copyrel-relro2.sh diff --git a/elf/input-files.cc b/elf/input-files.cc index fb2efc317c..1a44021843 100644 --- a/elf/input-files.cc +++ b/elf/input-files.cc @@ -1538,7 +1538,8 @@ bool SharedFile::is_readonly(Symbol *sym) { u64 val = sym->esym().st_value; for (ElfPhdr &phdr : this->get_phdrs()) - if (phdr.p_type == PT_LOAD && !(phdr.p_flags & PF_W) && + if ((phdr.p_type == PT_LOAD || phdr.p_type == PT_GNU_RELRO) && + !(phdr.p_flags & PF_W) && phdr.p_vaddr <= val && val < phdr.p_vaddr + phdr.p_memsz) return true; return false; diff --git a/test/elf/copyrel-relro2.sh b/test/elf/copyrel-relro2.sh new file mode 100755 index 0000000000..6e7bd187ab --- /dev/null +++ b/test/elf/copyrel-relro2.sh @@ -0,0 +1,40 @@ +#!/bin/bash +. $(dirname $0)/common.inc + +cat < +#include +#include + +extern 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() { + 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 + +cat <