From: Ivo Raisr Date: Mon, 11 Jul 2016 21:05:03 +0000 (+0000) Subject: Set executable protection on schedctl pages only when necessary. X-Git-Tag: svn/VALGRIND_3_12_0~120 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=86203023fa8d1d9084abd7e428dda2789728c684;p=thirdparty%2Fvalgrind.git Set executable protection on schedctl pages only when necessary. n-i-bz git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15903 --- diff --git a/configure.ac b/configure.ac index dd4fcb93fa..da433137b9 100644 --- a/configure.ac +++ b/configure.ac @@ -3604,6 +3604,51 @@ if test "$solaris_fpchip_state_takes_underscore" = "yes"; then [Define to 1 if fpregset_t defines struct _fpchip_state]) fi + +# Solaris-specific check determining if schedctl page shared between kernel +# and userspace program is executable (illumos, older Solaris) or not (newer +# Solaris). +# +# C-level symbol: SOLARIS_SCHEDCTL_PAGE_EXEC +# Automake-level symbol: none +# +AC_MSG_CHECKING([if schedctl page is executable (Solaris-specific)]) +AC_RUN_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include +#include +#include +#include +]], [[ + schedctl_t *scp = schedctl_init(); + if (scp == NULL) + return 1; + + int fd = open("/proc/self/map", O_RDONLY); + assert(fd >= 0); + + prmap_t map; + ssize_t rd; + while ((rd = read(fd, &map, sizeof(map))) == sizeof(map)) { + if (map.pr_vaddr == ((uintptr_t) scp & PAGEMASK)) { + fprintf(stderr, "%#lx [%zu] %s\n", map.pr_vaddr, map.pr_size, + (map.pr_mflags & MA_EXEC) ? "x" : "no-x"); + return (map.pr_mflags & MA_EXEC); + } + } + + return 1; +]])], [ +solaris_schedctl_page_exec=no +AC_MSG_RESULT([no]) +], [ +solaris_schedctl_page_exec=yes +AC_MSG_RESULT([yes]) +AC_DEFINE([SOLARIS_SCHEDCTL_PAGE_EXEC], 1, + [Define to 1 if you have the schedctl page executable.]) +]) + else AM_CONDITIONAL(SOLARIS_SUN_STUDIO_AS, false) AM_CONDITIONAL(SOLARIS_XPG_SYMBOLS_PRESENT, false) diff --git a/coregrind/m_syswrap/syswrap-solaris.c b/coregrind/m_syswrap/syswrap-solaris.c index 84c9ff2f5e..c0bea44be3 100644 --- a/coregrind/m_syswrap/syswrap-solaris.c +++ b/coregrind/m_syswrap/syswrap-solaris.c @@ -9427,7 +9427,10 @@ POST(sys_schedctl) /* Returned address points to a block in a mapped page. */ if (!VG_(am_find_anon_segment)(a)) { Addr page = VG_PGROUNDDN(a); - UInt prot = VKI_PROT_READ | VKI_PROT_WRITE | VKI_PROT_EXEC; + UInt prot = VKI_PROT_READ | VKI_PROT_WRITE; +# if defined(SOLARIS_SCHEDCTL_PAGE_EXEC) + prot |= VKI_PROT_EXEC; +# endif /* SOLARIS_SCHEDCTL_PAGE_EXEC */ UInt flags = VKI_MAP_ANONYMOUS; /* The kernel always allocates one page for the sc_shared struct. */ SizeT size = VKI_PAGE_SIZE;