From 9a789d726df714a3f6fd32b787930f8cbcedfac8 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Sat, 18 Mar 2023 12:14:42 +0000 Subject: [PATCH] file: Extend RELRO check to check for BIND_NOW Signed-off-by: Michael Tremer --- src/libpakfire/file.c | 60 ++++++++++++++++++++------- src/libpakfire/include/pakfire/file.h | 2 +- 2 files changed, 45 insertions(+), 17 deletions(-) diff --git a/src/libpakfire/file.c b/src/libpakfire/file.c index 10cd8439..fa6fc0a7 100644 --- a/src/libpakfire/file.c +++ b/src/libpakfire/file.c @@ -650,9 +650,9 @@ char* pakfire_file_dump(struct pakfire_file* file, int flags) { goto ERROR; } - // Not Partially RELRO - if (file->issues & PAKFIRE_FILE_NO_PARTIALLY_RELRO) { - r = asprintf(&buffer, "%s [NO-PART-RELRO]", buffer); + // Not RELRO + if (file->issues & PAKFIRE_FILE_NO_RELRO) { + r = asprintf(&buffer, "%s [NO-RELRO]", buffer); if (r < 0) goto ERROR; } @@ -1939,27 +1939,55 @@ 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_check_partially_relro( +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; + + switch (dyn->d_tag) { + case DT_BIND_NOW: + *has_bind_now = 1; + break; + + case DT_FLAGS: + if (dyn->d_un.d_val & DF_BIND_NOW) + *has_bind_now = 1; + break; + + case DT_FLAGS_1: + if (dyn->d_un.d_val & DF_1_NOW) + *has_bind_now = 1; + break; + + default: + break; + } + + return 0; +} + +static int __pakfire_file_check_relro( struct pakfire_file* file, Elf* elf, void* data) { + int has_bind_now = 0; GElf_Phdr phdr; int r; - size_t phnum = 0; + // Check if we have BIND_NOW + r = pakfire_file_elf_dyn_walk(file, elf, + __pakfire_file_process_bind_now, &has_bind_now); + if (r) + return r; - // 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; + // We are not fully RELRO + if (!has_bind_now) { + file->issues |= PAKFIRE_FILE_NO_RELRO; + + return 0; } // 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; - } + for (unsigned int i = 0;; i++) { + if (!gelf_getphdr(elf, i, &phdr)) + break; switch (phdr.p_type) { case PT_GNU_RELRO: diff --git a/src/libpakfire/include/pakfire/file.h b/src/libpakfire/include/pakfire/file.h index 0308daf2..431702ff 100644 --- a/src/libpakfire/include/pakfire/file.h +++ b/src/libpakfire/include/pakfire/file.h @@ -181,7 +181,7 @@ enum pakfire_file_check_issues { PAKFIRE_FILE_MISSING_SSP = (1 << 2), PAKFIRE_FILE_MISSING_PIE = (1 << 3), PAKFIRE_FILE_EXECSTACK = (1 << 4), - PAKFIRE_FILE_NO_PARTIALLY_RELRO = (1 << 5), + PAKFIRE_FILE_NO_RELRO = (1 << 5), PAKFIRE_FILE_HAS_RUNPATH = (1 << 6), }; -- 2.39.5