Changeset View
Changeset View
Standalone View
Standalone View
lib/libc/gen/elf_utils.c
Show All 22 Lines | |||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
* SUCH DAMAGE. | * SUCH DAMAGE. | ||||
* | * | ||||
* $FreeBSD$ | * $FreeBSD$ | ||||
*/ | */ | ||||
#include <sys/types.h> | #include <sys/param.h> | ||||
#include <sys/auxv.h> | |||||
#include <sys/mman.h> | #include <sys/mman.h> | ||||
#include <sys/resource.h> | #include <sys/resource.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <link.h> | #include <link.h> | ||||
#include <stddef.h> | #include <stddef.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include "libc_private.h" | #include "libc_private.h" | ||||
#include "static_tls.h" | #include "static_tls.h" | ||||
Show All 32 Lines | #endif | ||||
return (i != phdr_info->dlpi_phnum); | return (i != phdr_info->dlpi_phnum); | ||||
} | } | ||||
void | void | ||||
__libc_map_stacks_exec(void) | __libc_map_stacks_exec(void) | ||||
{ | { | ||||
int mib[2]; | int mib[2]; | ||||
struct rlimit rlim; | struct rlimit rlim; | ||||
u_long usrstack; | u_long usrstack, stacksz; | ||||
size_t len; | size_t len; | ||||
if (_elf_aux_info(AT_USRSTACKBASE, &usrstack, sizeof(usrstack)) != 0) { | |||||
mib[0] = CTL_KERN; | mib[0] = CTL_KERN; | ||||
mib[1] = KERN_USRSTACK; | mib[1] = KERN_USRSTACK; | ||||
len = sizeof(usrstack); | len = sizeof(usrstack); | ||||
if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &usrstack, &len, NULL, 0) | if (sysctl(mib, nitems(mib), &usrstack, &len, NULL, 0) == -1) | ||||
== -1) | |||||
return; | return; | ||||
} | |||||
if (_elf_aux_info(AT_USRSTACKLIM, &stacksz, sizeof(stacksz)) != 0) { | |||||
if (getrlimit(RLIMIT_STACK, &rlim) == -1) | if (getrlimit(RLIMIT_STACK, &rlim) == -1) | ||||
return; | return; | ||||
mprotect((void *)(uintptr_t)(usrstack - rlim.rlim_cur), | stacksz = rlim.rlim_cur; | ||||
rlim.rlim_cur, _rtld_get_stack_prot()); | } | ||||
mprotect((void *)(uintptr_t)(usrstack - stacksz), stacksz, | |||||
_rtld_get_stack_prot()); | |||||
markj: I think this can't work on CHERI, since it relies on being able to forge a pointer from u_longs… | |||||
kibAuthorUnsubmitted Done Inline ActionsYes, KERN_USRSTACK is same. This is why I selected a_un.a_val for AT_USRSTACKLIM. kib: Yes, KERN_USRSTACK is same. This is why I selected a_un.a_val for AT_USRSTACKLIM. | |||||
} | } | ||||
#pragma weak __pthread_map_stacks_exec | #pragma weak __pthread_map_stacks_exec | ||||
void | void | ||||
__pthread_map_stacks_exec(void) | __pthread_map_stacks_exec(void) | ||||
{ | { | ||||
((void (*)(void))__libc_interposing[INTERPOS_map_stacks_exec])(); | ((void (*)(void))__libc_interposing[INTERPOS_map_stacks_exec])(); | ||||
Show All 22 Lines |
I think this can't work on CHERI, since it relies on being able to forge a pointer from u_longs provided by the kernel. Should we instead make the type of the USRSTACKBASE entry a uintptr_t instead? @jhb or @jrtc27 or @brooks might have an opinion. Though, it looks like this problem exists with KERN_USRSTACK today in CheriBSD, so maybe they don't care about supporting executable stacks.