diff -uNrp glibc-2.3.6.old/elf/dl-load.c glibc-2.3.6/elf/dl-load.c --- glibc-2.3.6.old/elf/dl-load.c 2005-04-06 06:50:10.000000000 +0400 +++ glibc-2.3.6/elf/dl-load.c 2012-08-05 20:51:30.325664089 +0400 @@ -938,7 +938,11 @@ _dl_map_object_from_fd (const char *name } /* Presumed absent PT_GNU_STACK. */ - uint_fast16_t stack_flags = PF_R|PF_W|PF_X; + uint_fast16_t stack_flags; + if (GL(dl_no_gnu_stack_force_nx)) + stack_flags = PF_R|PF_W; + else + stack_flags = PF_R|PF_W|PF_X; { /* Scan the program header table, collecting its load commands. */ @@ -1097,6 +1101,8 @@ cannot allocate TLS data structures for case PT_GNU_STACK: stack_flags = ph->p_flags; + if (GL(dl_gnu_stack_x_force_nx)) + stack_flags &= ~PF_X; break; case PT_GNU_RELRO: diff -uNrp glibc-2.3.6.old/elf/dl-support.c glibc-2.3.6/elf/dl-support.c --- glibc-2.3.6.old/elf/dl-support.c 2004-11-06 03:24:49.000000000 +0300 +++ glibc-2.3.6/elf/dl-support.c 2012-08-05 20:32:32.103705665 +0400 @@ -125,6 +125,8 @@ unsigned long int _dl_hwcap __attribute_ /* Prevailing state of the stack, PF_X indicating it's executable. */ ElfW(Word) _dl_stack_flags = PF_R|PF_W|PF_X; +bool _dl_no_gnu_stack_force_nx = false; +bool _dl_gnu_stack_x_force_nx = false; /* If loading a shared object requires that we make the stack executable when it was not, we do it by calling this function. diff -uNrp glibc-2.3.6.old/sysdeps/generic/dl-sysdep.c glibc-2.3.6/sysdeps/generic/dl-sysdep.c --- glibc-2.3.6.old/sysdeps/generic/dl-sysdep.c 2004-11-06 03:24:47.000000000 +0300 +++ glibc-2.3.6/sysdeps/generic/dl-sysdep.c 2012-08-05 20:51:12.689576638 +0400 @@ -157,6 +157,12 @@ _dl_sysdep_start (void **start_argptr, case AT_FPUCW: GLRO(dl_fpu_control) = av->a_un.a_val; break; + case AT_FLAGS: + if (av->a_un.a_val & 1) + GL(dl_gnu_stack_x_force_nx) = true; + if (av->a_un.a_val & 2) + GL(dl_no_gnu_stack_force_nx) = true; + break; #ifdef NEED_DL_SYSINFO case AT_SYSINFO: new_sysinfo = av->a_un.a_val; diff -uNrp glibc-2.3.6.old/sysdeps/generic/ldsodefs.h glibc-2.3.6/sysdeps/generic/ldsodefs.h --- glibc-2.3.6.old/sysdeps/generic/ldsodefs.h 2005-04-06 06:50:21.000000000 +0400 +++ glibc-2.3.6/sysdeps/generic/ldsodefs.h 2012-08-04 12:49:18.562722134 +0400 @@ -288,6 +288,8 @@ struct rtld_global /* Prevailing state of the stack, PF_X indicating it's executable. */ EXTERN ElfW(Word) _dl_stack_flags; + EXTERN bool _dl_gnu_stack_x_force_nx; + EXTERN bool _dl_no_gnu_stack_force_nx; /* If loading a shared object requires that we make the stack executable when it was not, we do it by calling this function.