While attempting to audit a Gentoo binary for no-exec heap compliance, it appears both executable heaps and non-executable heaps use the same ELF section markings: ** No-Exec Heap ** gentoo@Gentoo-2012 ~ $ g++ -g3 -O0 -Wall -Wextra -Wconversion -fPIE -pie -fstack-protector-all sample.cpp -o sample.exe -Wl,-z,noexecstack -Wl,-z,noexecheap -Wl,-z,relro -Wl,-z,now gentoo@Gentoo-2012 ~ $ readelf -l sample.exe | grep -A 1 -i "PAX_FLAGS" PAX_FLAGS 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 8 ** Exec Heap ** gentoo@Gentoo-2012 ~ $ g++ -g3 -O0 -Wall -Wextra -Wconversion -fPIE -pie -fstack-protector-all sample.cpp -o sample.exe -Wl,-z,noexecstack -Wl,-z,execheap -Wl,-z,relro -Wl,-z,now gentoo@Gentoo-2012 ~ $ readelf -l sample.exe | grep -A 1 -i "PAX_FLAGS" PAX_FLAGS 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 8 Looking further, it appears readelf.c does not include any code to display information on the markings (from the changes in 63-all-binutils-2.23...patch): --- binutils-2.23.51.0.1/binutils/readelf.c +++ binutils-2.23.51.0.1/binutils/readelf.c @@ -2740,6 +2740,7 @@ get_segment_type (unsigned long p_type) return "GNU_EH_FRAME"; case PT_GNU_STACK: return "GNU_STACK"; case PT_GNU_RELRO: return "GNU_RELRO"; + case PT_PAX_FLAGS: return "PAX_FLAGS"; default: if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC)) Lack of full support makes it difficult for folks who need to audit systems and programs. Reproducible: Always Steps to Reproduce: Compile a program and link with `-z,execheap` and `-z,noexecheap`. Notice there is no difference in output when auditing with `readelf -l`. Expected Results: Proper dump of the PAX_FLAGS segment.
When performing a similar audit on no-exec stacks using "GNU_STACK", readelf -l will display RW (-z,noexecstack) or RWE (-z,execstack).
use `scanelf -x` to analyze settings we're in the process of deprecating PT_PAX_FLAGS, so not much point in extending support for it further
(In reply to comment #2) > use `scanelf -x` to analyze settings > > we're in the process of deprecating PT_PAX_FLAGS, so not much point in > extending support for it further Thanks spanKY. scanelf(1) did not discuss the output of the -x (--pax) option. Can we assume we want a `M' (capitol M), and not `m' (lower m)? ** No-Exec Heap ** $ g++ -g3 -O0 -Wall -Wextra -Wconversion -fPIE -pie -fstack-protector-all sample.cpp -o sample.exe -Wl,-z,noexecstack -Wl,-z,noexecheap -Wl,-z,relro -Wl,-z,now $ scanelf -x sample.exe TYPE PAX FILE ET_DYN --Mxe- sample.exe ** Exec Heap ** $ g++ -g3 -O0 -Wall -Wextra -Wconversion -fPIE -pie -fstack-protector-all sample.cpp -o sample.exe -Wl,-z,noexecstack -Wl,-z,execheap -Wl,-z,relro -Wl,-z,now $ scanelf -x sample.exe TYPE PAX FILE ET_DYN --mxe- sample.exe
(In reply to comment #3) /* PT_PAX_FLAGS are tristate ... * the display logic is: * lower case: explicitly disabled * upper case: explicitly enabled * - : default */ buffer[0] = PAX_STATE(PF_PAGEEXEC, PF_NOPAGEEXEC, 'P', 'p'); buffer[1] = PAX_STATE(PF_SEGMEXEC, PF_NOSEGMEXEC, 'S', 's'); buffer[2] = PAX_STATE(PF_MPROTECT, PF_NOMPROTECT, 'M', 'm'); buffer[3] = PAX_STATE(PF_RANDEXEC, PF_NORANDEXEC, 'X', 'x'); buffer[4] = PAX_STATE(PF_EMUTRAMP, PF_NOEMUTRAMP, 'E', 'e'); buffer[5] = PAX_STATE(PF_RANDMMAP, PF_NORANDMMAP, 'R', 'r');