]> git.ipfire.org Git - people/stevee/pakfire.git/commitdiff
file: Extend RELRO check to check for BIND_NOW
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 18 Mar 2023 12:14:42 +0000 (12:14 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 18 Mar 2023 12:14:42 +0000 (12:14 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/file.c
src/libpakfire/include/pakfire/file.h

index 10cd8439a808d24f66602f3165ead10de2cd78d8..fa6fc0a7b9422653fa8f01bef899066b7ce1fd25 100644 (file)
@@ -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:
index 0308daf28314e2ffc03b2198f03b7297b35a663e..431702ffe8b3d017f1a85e6d852b44ed925902ed 100644 (file)
@@ -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),
 };