The branch main has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=81b3a0a34145ee6c855f50c8035728f76d63c3f0

commit 81b3a0a34145ee6c855f50c8035728f76d63c3f0
Author:     Konstantin Belousov <k...@freebsd.org>
AuthorDate: 2021-01-10 03:05:42 +0000
Commit:     Konstantin Belousov <k...@freebsd.org>
CommitDate: 2021-01-10 06:25:43 +0000

    libc: implement rtld_get_stack_prot() for real
    
    which makes stack prot correct for non-main threads created by binaries
    with statically linked libthr.
    
    Cache result, but do not engage into the full double-checked locking,
    since calculation of the return value is idempotent.
    
    PR:     252549
    Reported and reviewed by:       emaste
    MFC after:      1 week
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D28075
---
 lib/libc/gen/dlfcn.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/lib/libc/gen/dlfcn.c b/lib/libc/gen/dlfcn.c
index f7f162753b4b..395a6d9402e8 100644
--- a/lib/libc/gen/dlfcn.c
+++ b/lib/libc/gen/dlfcn.c
@@ -34,7 +34,9 @@ __FBSDID("$FreeBSD$");
 /*
  * Linkage to services provided by the dynamic linker.
  */
+#include <sys/types.h>
 #include <sys/mman.h>
+#include <machine/atomic.h>
 #include <dlfcn.h>
 #include <link.h>
 #include <stddef.h>
@@ -256,8 +258,30 @@ _rtld_addr_phdr(const void *addr __unused,
 int
 _rtld_get_stack_prot(void)
 {
+#ifndef IN_LIBDL
+       unsigned i;
+       int r;
+       static int ret;
+
+       r = atomic_load_int(&ret);
+       if (r != 0)
+               return (r);
 
-       return (PROT_EXEC | PROT_READ | PROT_WRITE);
+       _once(&dl_phdr_info_once, dl_init_phdr_info);
+       r = PROT_EXEC | PROT_READ | PROT_WRITE;
+       for (i = 0; i < phdr_info.dlpi_phnum; i++) {
+               if (phdr_info.dlpi_phdr[i].p_type != PT_GNU_STACK)
+                       continue;
+               r = PROT_READ | PROT_WRITE;
+               if ((phdr_info.dlpi_phdr[i].p_flags & PF_X) != 0)
+                       r |= PROT_EXEC;
+               break;
+       }
+       atomic_store_int(&ret, r);
+       return (r);
+#else
+       return (0);
+#endif
 }
 
 #pragma weak _rtld_is_dlopened
_______________________________________________
dev-commits-src-main@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main
To unsubscribe, send any mail to "dev-commits-src-main-unsubscr...@freebsd.org"

Reply via email to