From: Michael Tremer Date: Fri, 3 Jan 2025 08:42:07 +0000 (+0000) Subject: ELF: Create a function to easily walk through all program headers X-Git-Tag: 0.9.30~571 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=40b7c05b2dea72c83c0548cc15394765d43c4e41;p=pakfire.git ELF: Create a function to easily walk through all program headers Signed-off-by: Michael Tremer --- diff --git a/src/pakfire/elf.c b/src/pakfire/elf.c index 10f25a22b..c6c681fab 100644 --- a/src/pakfire/elf.c +++ b/src/pakfire/elf.c @@ -282,6 +282,30 @@ const char* pakfire_elf_debuglink(struct pakfire_elf* self) { return self->debuglink; } +typedef int (*pakfire_elf_foreach_program_header_callback) + (struct pakfire_elf* self, const GElf_Phdr* phdr, void* data); + +static int pakfire_elf_foreach_program_header(struct pakfire_elf* self, + pakfire_elf_foreach_program_header_callback callback, void* data) { + GElf_Phdr phdr = {}; + int r; + + // Walk through all program headers + for (unsigned int i = 0; i < self->phnum; i++) { + if (!gelf_getphdr(self->elf, i, &phdr)) { + ERROR(self->ctx, "Could not parse program header: %s\n", elf_errmsg(-1)); + return -ENOTSUP; + } + + // Call the callback + r = callback(self, &phdr, data); + if (r) + break; + } + + return r; +} + static int pakfire_elf_get_section(struct pakfire_elf* self, const Elf64_Word type, const char* name, Elf_Scn** section, GElf_Shdr* header, Elf_Data** data) { const char* sname = NULL; @@ -480,38 +504,33 @@ int pakfire_elf_has_ssp(struct pakfire_elf* self) { return 0; } -int pakfire_elf_has_execstack(struct pakfire_elf* self) { - GElf_Phdr phdr; - - // Walk through all program headers - for (unsigned int i = 0; i < self->phnum; i++) { - if (!gelf_getphdr(self->elf, i, &phdr)) { - ERROR(self->ctx, "Could not parse program header: %s\n", elf_errmsg(-1)); - return -ENOTSUP; - } - - switch (phdr.p_type) { - case PT_GNU_STACK: - DEBUG(self->ctx, - "%s: GNU_STACK flags: %c%c%c\n", - self->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 1; +static int pakfire_elf_check_execstack( + struct pakfire_elf* self, const GElf_Phdr* phdr, void* data) { + switch (phdr->p_type) { + case PT_GNU_STACK: + DEBUG(self->ctx, + "%s: GNU_STACK flags: %c%c%c\n", + self->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 1; - default: - break; - } + default: + break; } return 0; } +int pakfire_elf_has_execstack(struct pakfire_elf* self) { + return pakfire_elf_foreach_program_header(self, pakfire_elf_check_execstack, NULL); +} + static int pakfire_elf_has_bind_now(struct pakfire_elf* self, const GElf_Shdr* shdr, const GElf_Dyn* dyn, void* data) { switch (dyn->d_tag) {