File tree Expand file tree Collapse file tree 3 files changed +20
-1
lines changed
Expand file tree Collapse file tree 3 files changed +20
-1
lines changed Original file line number Diff line number Diff line change @@ -1017,7 +1017,8 @@ jobs:
10171017 -DCMAKE_BUILD_TYPE=Debug \
10181018 -DCPPTRACE_WERROR_BUILD=On \
10191019 -DCPPTRACE_STD_FORMAT=Off \
1020- -DCPPTRACE_BUILD_TESTING=On
1020+ -DCPPTRACE_BUILD_TESTING=On \
1021+ -DCMAKE_EXE_LINKER_FLAGS="-Wl,-z,norelro"
10211022 ninja
10221023 ./unittest
10231024
Original file line number Diff line number Diff line change @@ -294,13 +294,28 @@ namespace detail {
294294 if (type_info_addr - page_addr + sizeof (void *) > static_cast <unsigned >(page_size)) {
295295 throw internal_error (" pointer crosses page boundaries" );
296296 }
297+ #if IS_WINDOWS
297298 auto old_protections = mprotect_page_and_return_old_protections (
298299 reinterpret_cast <void *>(page_addr),
299300 page_size,
300301 memory_readwrite
301302 );
302303 *static_cast <void **>(type_info_pointer) = static_cast <void *>(new_vtable + 2 );
303304 mprotect_page (reinterpret_cast <void *>(page_addr), page_size, old_protections);
305+ #else
306+ auto old_protections = get_page_protections (reinterpret_cast <void *>(page_addr));
307+ // If the page is already writable, skip mprotect entirely.
308+ // This isn't just an optimization, it's needed on openbsd where mprotect would fail with EPERM but we can use
309+ // -Wl,-z,norelro to make the pages we care about writable
310+ bool need_mprotect = !(old_protections & PROT_WRITE);
311+ if (need_mprotect) {
312+ mprotect_page (reinterpret_cast <void *>(page_addr), page_size, memory_readwrite);
313+ }
314+ *static_cast <void **>(type_info_pointer) = static_cast <void *>(new_vtable + 2 );
315+ if (need_mprotect) {
316+ mprotect_page (reinterpret_cast <void *>(page_addr), page_size, old_protections);
317+ }
318+ #endif
304319 }
305320
306321 bool can_catch (
Original file line number Diff line number Diff line change @@ -21,6 +21,9 @@ namespace detail {
2121 constexpr auto memory_readwrite = PROT_READ | PROT_WRITE;
2222 #endif
2323 int get_page_size ();
24+ #if !IS_WINDOWS
25+ int get_page_protections (void * page);
26+ #endif
2427 int mprotect_page_and_return_old_protections (void * page, int page_size, int protections);
2528 void mprotect_page (void * page, int page_size, int protections);
2629 void * allocate_page (int page_size);
You can’t perform that action at this time.
0 commit comments