return pakfire_file_open_elf(file, __pakfire_file_hardening_check_pie, NULL);
}
+static int __pakfire_file_hardening_check_execstack(
+ struct pakfire_file* file, Elf* elf, void* data) {
+ GElf_Phdr phdr;
+ int r;
+
+ size_t phnum = 0;
+
+ // Fetch the total numbers of program headers
+ r = elf_getphdrnum(elf, &phnum);
+ if (r) {
+ ERROR(file->pakfire, "Could not fetch number of program headers: %s\n",
+ elf_errmsg(-1));
+ return 1;
+ }
+
+ // Walk through all program headers
+ for (unsigned int i = 0; i < phnum; i++) {
+ if (!gelf_getphdr(elf, i, &phdr)) {
+ ERROR(file->pakfire, "Could not parse program header: %s\n", elf_errmsg(-1));
+ return 1;
+ }
+
+ switch (phdr.p_type) {
+ case PT_GNU_STACK:
+ DEBUG(file->pakfire,
+ "%s: GNU_STACK flags: %c%c%c\n",
+ file->path,
+ (phdr.p_flags & PF_R) ? 'R' : '-',
+ (phdr.p_flags & PF_W) ? 'W' : '-',
+ (phdr.p_flags & PF_X) ? 'X' : '-'
+ );
+
+ // The stack cannot be writable and executable
+ if ((phdr.p_flags & PF_W) && (phdr.p_flags & PF_X))
+ file->hardening_issues |= PAKFIRE_FILE_EXECSTACK;
+
+ // Done
+ return 0;
+
+ default:
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int pakfire_file_hardening_check_execstack(struct pakfire_file* file) {
+ return pakfire_file_open_elf(file, __pakfire_file_hardening_check_execstack, NULL);
+}
+
int pakfire_file_check_hardening(struct pakfire_file* file, int* issues) {
int r;
if (r)
return r;
+ // Check for executable stacks
+ r = pakfire_file_hardening_check_execstack(file);
+ if (r)
+ return r;
+
// All checks done
file->hardening_check_done = 1;
}
enum pakfire_file_hardening_flags {
PAKFIRE_FILE_NO_SSP = (1 << 0),
PAKFIRE_FILE_NO_PIE = (1 << 1),
+ PAKFIRE_FILE_EXECSTACK = (1 << 2),
};
int pakfire_file_check_hardening(struct pakfire_file* file, int* issues);
return 1
fi
- local exec_stack=()
local not_relro=()
local partly_relro=()
continue
fi
- # Does this file have an executable stack?
- if readelf -l "${file}" 2>/dev/null | grep -A1 "GNU_STACK" | grep -q "RWE"; then
- exec_stack+=( "${file}" )
- fi
-
# Perform more checks for shared objects (i.e. libraries)
if file "${file}" | grep -q "shared object"; then
# Is this file partly RELRO?
local r=0
- # Log files with an executable stack
- if [ "${#exec_stack[@]}" -gt 0 ]; then
- error "The following files have an executable stack:"
- for file in ${exec_stack[@]}; do
- error " ${file/${buildroot}/}"
- done
-
- r=1
- fi
-
# Log files which are not RELRO
if [ "${#not_relro[@]}" -gt 0 ]; then
error "The following files are not fully RELRO:"