From fca84c63b5b26ff362593c5a9479d8a48e7572ec Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Sat, 26 Oct 2024 11:22:20 +0000 Subject: [PATCH] linter: Check for executable stacks Signed-off-by: Michael Tremer --- src/libpakfire/file.c | 63 --------------------------- src/libpakfire/include/pakfire/file.h | 1 - src/libpakfire/linter-file.c | 53 ++++++++++++++++++++++ 3 files changed, 53 insertions(+), 64 deletions(-) diff --git a/src/libpakfire/file.c b/src/libpakfire/file.c index 9f590f76a..f4bc1bde3 100644 --- a/src/libpakfire/file.c +++ b/src/libpakfire/file.c @@ -752,13 +752,6 @@ char* pakfire_file_dump(struct pakfire_file* file, int flags) { goto ERROR; } - // Executable Stack - if (file->issues & PAKFIRE_FILE_EXECSTACK) { - r = asprintf(&buffer, "%s [EXECSTACK]", buffer); - if (r < 0) - goto ERROR; - } - // Not RELRO if (file->issues & PAKFIRE_FILE_NO_RELRO) { r = asprintf(&buffer, "%s [NO-RELRO]", buffer); @@ -2025,57 +2018,6 @@ static int pakfire_file_check_debuginfo(struct pakfire_file* file) { return pakfire_file_open_elf(file, __pakfire_file_check_debuginfo, NULL); } -static int __pakfire_file_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->ctx, "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->ctx, "Could not parse program header: %s\n", elf_errmsg(-1)); - return 1; - } - - switch (phdr.p_type) { - case PT_GNU_STACK: - DEBUG(file->ctx, - "%s: GNU_STACK flags: %c%c%c\n", - pakfire_file_get_path(file), - (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->issues |= PAKFIRE_FILE_EXECSTACK; - - // Done - return 0; - - default: - break; - } - } - - return 0; -} - -static int pakfire_file_check_execstack(struct pakfire_file* file) { - return pakfire_file_open_elf(file, __pakfire_file_check_execstack, NULL); -} - static int __pakfire_file_process_bind_now(struct pakfire_file* file, Elf* elf, const GElf_Shdr* shdr, const GElf_Dyn* dyn, void* data) { int* has_bind_now = (int*)data; @@ -2732,11 +2674,6 @@ int pakfire_file_check(struct pakfire_file* file, int* issues) { if (r) return r; - // Check for executable stacks - r = pakfire_file_check_execstack(file); - if (r) - return r; - // Check for RELRO r = pakfire_file_check_relro(file); if (r) diff --git a/src/libpakfire/include/pakfire/file.h b/src/libpakfire/include/pakfire/file.h index 66f15c920..2f925413e 100644 --- a/src/libpakfire/include/pakfire/file.h +++ b/src/libpakfire/include/pakfire/file.h @@ -187,7 +187,6 @@ int pakfire_file_verify(struct pakfire_file* file, int* status); enum pakfire_file_check_issues { PAKFIRE_FILE_FHS_ERROR = (1 << 0), PAKFIRE_FILE_MISSING_DEBUGINFO = (1 << 1), - PAKFIRE_FILE_EXECSTACK = (1 << 4), PAKFIRE_FILE_NO_RELRO = (1 << 5), PAKFIRE_FILE_HAS_RUNPATH = (1 << 6), PAKFIRE_FILE_INVALID_CAPS = (1 << 7), diff --git a/src/libpakfire/linter-file.c b/src/libpakfire/linter-file.c index 5b4fe29bd..ae1ed8830 100644 --- a/src/libpakfire/linter-file.c +++ b/src/libpakfire/linter-file.c @@ -364,6 +364,54 @@ static int pakfire_linter_file_check_ssp(struct pakfire_linter_file* lfile) { return pakfire_linter_file_elf(lfile, __pakfire_linter_file_check_ssp, NULL); } +static int __pakfire_linter_file_check_execstack( + struct pakfire_linter_file* lfile, 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(lfile->ctx, + "Could not fetch number of program headers: %s\n", elf_errmsg(-1)); + return -EINVAL; + } + + // Walk through all program headers + for (unsigned int i = 0; i < phnum; i++) { + if (!gelf_getphdr(elf, i, &phdr)) { + ERROR(lfile->ctx, "Could not parse program header: %s\n", elf_errmsg(-1)); + return -ENOTSUP; + } + + switch (phdr.p_type) { + case PT_GNU_STACK: + DEBUG(lfile->ctx, + "%s: GNU_STACK flags: %c%c%c\n", + lfile->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)) + return pakfire_linter_file_error(lfile->linter, lfile->file, "Executable Stack"); + + default: + break; + } + } + + return 0; +} + +static int pakfire_linter_file_check_execstack(struct pakfire_linter_file* lfile) { + return pakfire_linter_file_elf(lfile, __pakfire_linter_file_check_execstack, NULL); +} + int pakfire_linter_file_lint(struct pakfire_linter_file* lfile) { int r = 0; @@ -390,6 +438,11 @@ int pakfire_linter_file_lint(struct pakfire_linter_file* lfile) { r = pakfire_linter_file_check_ssp(lfile); if (r < 0) return r; + + // Check for Executable Stacks + r = pakfire_linter_file_check_execstack(lfile); + if (r < 0) + return r; } return 0; -- 2.39.5