]> git.ipfire.org Git - pakfire.git/commitdiff
linter: Move the ELF stuff to the file stuff
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 25 Oct 2024 17:33:34 +0000 (17:33 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 25 Oct 2024 17:33:34 +0000 (17:33 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/include/pakfire/linter-file.h
src/libpakfire/linter-file.c
src/libpakfire/linter.c

index 4a57fec994a10e37b5c47bbc83479448ee03f8f8..976f2356a403444cb6f5acef1778fea9f355ce9d 100644 (file)
@@ -35,5 +35,7 @@ int pakfire_linter_file_create(struct pakfire_linter_file** lfile,
 struct pakfire_linter_file* pakfire_linter_file_ref(struct pakfire_linter_file* lfile);
 struct pakfire_linter_file* pakfire_linter_file_unref(struct pakfire_linter_file* lfile);
 
+int pakfire_linter_file_lint(struct pakfire_linter_file* lfile);
+
 #endif /* PAKFIRE_PRIVATE */
 #endif /* PAKFIRE_LINTER_FILE_H */
index 4d1d2c73afcdcfe6dec8f4e5e34946f2cf96b5c4..879d93708437afd283ee35841a731839f6d401f8 100644 (file)
@@ -21,6 +21,9 @@
 #include <errno.h>
 #include <stdlib.h>
 
+// libelf
+#include <gelf.h>
+
 #include <pakfire/ctx.h>
 #include <pakfire/file.h>
 #include <pakfire/linter.h>
@@ -38,6 +41,9 @@ struct pakfire_linter_file {
 
        // File Descriptor
        int fd;
+
+       // Path
+       const char* path;
 };
 
 int pakfire_linter_file_create(struct pakfire_linter_file** lfile,
@@ -66,6 +72,13 @@ int pakfire_linter_file_create(struct pakfire_linter_file** lfile,
        // Store a reference to the file
        l->file = pakfire_file_ref(file);
 
+       // Cache path
+       l->path = pakfire_file_get_path(l->file);
+       if (!l->path) {
+               r = -EINVAL;
+               goto ERROR;
+       }
+
        // Store the file descriptor
        l->fd = dup(fd);
        if (l->fd < 0) {
@@ -108,3 +121,148 @@ struct pakfire_linter_file* pakfire_linter_file_unref(struct pakfire_linter_file
        pakfire_linter_file_free(lfile);
        return NULL;
 }
+
+static int pakfire_linter_file_init_libelf(struct pakfire_linter_file* lfile) {
+       // Initialize libelf
+       if (elf_version(EV_CURRENT) == EV_NONE) {
+               ERROR(lfile->ctx, "Could not initialize libelf: %s\n", elf_errmsg(-1));
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int pakfire_linter_file_is_elf(struct pakfire_linter_file* lfile) {
+       Elf* elf = NULL;
+       int r;
+
+       // Initialize libelf
+       r = pakfire_linter_file_init_libelf(lfile);
+       if (r < 0)
+               return r;
+
+       // Parse the ELF header
+       elf = elf_begin(lfile->fd, ELF_C_READ, NULL);
+       if (!elf) {
+               ERROR(lfile->ctx, "Could not open ELF file: %s\n", elf_errmsg(-1));
+               r = -EINVAL;
+               goto ERROR;
+       }
+
+       switch (elf_kind(elf)) {
+               case ELF_K_ELF:
+                       r = 1;
+                       break;
+
+               // Ignore everything else
+               default:
+                       r = 0;
+                       break;
+       }
+
+ERROR:
+       if (elf)
+               elf_end(elf);
+
+       return r;
+}
+
+/*
+       A helper function that opens an ELF file and calls a callback.
+*/
+static int pakfire_linter_file_elf(struct pakfire_linter_file* lfile,
+               int (*callback)(struct pakfire_linter_file* lfile, Elf* elf, void* data), void* data) {
+       Elf* elf = NULL;
+       int r;
+
+       // Initialize libelf
+       r = pakfire_linter_file_init_libelf(lfile);
+       if (r < 0)
+               return r;
+
+       // Parse the ELF header
+       elf = elf_begin(lfile->fd, ELF_C_READ, NULL);
+       if (!elf) {
+               ERROR(lfile->ctx, "Could not open ELF file: %s\n", elf_errmsg(-1));
+               r = -EINVAL;
+               goto ERROR;
+       }
+
+       // Check if this is an ELF file
+       switch (elf_kind(elf)) {
+               case ELF_K_ELF:
+                       break;
+
+               default:
+                       ERROR(lfile->ctx, "%s is not an ELF object\n", lfile->path);
+                       r = -EINVAL;
+                       goto ERROR;
+       }
+
+       // Call the callback
+       r = callback(lfile, elf, data);
+
+ERROR:
+       if (elf)
+               elf_end(elf);
+
+       return r;
+}
+
+static int __pakfire_linter_file_get_elf_type(
+               struct pakfire_linter_file* lfile, Elf* elf, void* data) {
+       GElf_Ehdr ehdr = {};
+
+       int* type = data;
+
+       // Fetch the ELF header
+       if (!gelf_getehdr(elf, &ehdr)) {
+               ERROR(lfile->ctx, "Could not parse ELF header: %s\n", elf_errmsg(-1));
+               return -EINVAL;
+       }
+
+       // Store the type
+       *type = ehdr.e_type;
+
+       return 0;
+}
+
+static int pakfire_linter_file_get_elf_type(struct pakfire_linter_file* lfile) {
+       int type = ET_NONE;
+       int r;
+
+       // Fetch the type
+       r = pakfire_linter_file_elf(lfile, __pakfire_linter_file_get_elf_type, &type);
+       if (r < 0)
+               return r;
+
+       return type;
+}
+
+static int pakfire_linter_file_check_pie(struct pakfire_linter_file* lfile) {
+       switch (pakfire_linter_file_get_elf_type(lfile)) {
+               // Shared Object files are good
+               case ET_DYN:
+                       return 0;
+
+               // Everything else is bad
+               default:
+                       break;
+       }
+
+       return pakfire_linter_error(lfile->linter, "%s is not PIE", lfile->path);
+}
+
+int pakfire_linter_file_lint(struct pakfire_linter_file* lfile) {
+       int r = 0;
+
+       // ELF Checks
+       if (pakfire_linter_file_is_elf(lfile)) {
+               // Check PIE
+               r = pakfire_linter_file_check_pie(lfile);
+               if (r < 0)
+                       return r;
+       }
+
+       return 0;
+}
index baf2872d4a2e6d17630098ee62fda04d1e5bfb20..3be333f365f84eded9462ff7991238e8f2be7aa0 100644 (file)
@@ -28,9 +28,6 @@
 #include <archive.h>
 #include <archive_entry.h>
 
-// libelf
-#include <gelf.h>
-
 #include <pakfire/archive.h>
 #include <pakfire/fhs.h>
 #include <pakfire/file.h>
@@ -214,145 +211,6 @@ void pakfire_linter_set_result_callback(struct pakfire_linter* linter,
        linter->result_data     = data;
 }
 
-/*
-       ELF Stuff
-*/
-
-static int pakfire_linter_init_libelf(struct pakfire_linter* linter) {
-       // Initialize libelf
-       if (elf_version(EV_CURRENT) == EV_NONE) {
-               ERROR(linter->ctx, "Could not initialize libelf: %s\n", elf_errmsg(-1));
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int pakfire_linter_file_is_elf(
-               struct pakfire_linter* linter, struct pakfire_file* file, int fd) {
-       Elf* elf = NULL;
-       int r;
-
-       // Initialize libelf
-       r = pakfire_linter_init_libelf(linter);
-       if (r < 0)
-               return r;
-
-       // Parse the ELF header
-       elf = elf_begin(fd, ELF_C_READ, NULL);
-       if (!elf) {
-               ERROR(linter->ctx, "Could not open ELF file: %s\n", elf_errmsg(-1));
-               r = -EINVAL;
-               goto ERROR;
-       }
-
-       switch (elf_kind(elf)) {
-               case ELF_K_ELF:
-                       r = 1;
-                       break;
-
-               // Ignore everything else
-               default:
-                       r = 0;
-                       break;
-       }
-
-ERROR:
-       if (elf)
-               elf_end(elf);
-
-       return r;
-}
-
-/*
-       A helper function that opens an ELF file and calls a callback.
-*/
-static int pakfire_linter_elf(struct pakfire_linter* linter, struct pakfire_file* file, int fd,
-               int (*callback)(struct pakfire_linter* linter, struct pakfire_file* file, Elf* elf, void* data),
-               void* data) {
-       Elf* elf = NULL;
-       int r;
-
-       // Initialize libelf
-       r = pakfire_linter_init_libelf(linter);
-       if (r < 0)
-               return r;
-
-       // Parse the ELF header
-       elf = elf_begin(fd, ELF_C_READ, NULL);
-       if (!elf) {
-               ERROR(linter->ctx, "Could not open ELF file: %s\n", elf_errmsg(-1));
-               r = -EINVAL;
-               goto ERROR;
-       }
-
-       // Check if this is an ELF file
-       switch (elf_kind(elf)) {
-               case ELF_K_ELF:
-                       break;
-
-               default:
-                       ERROR(linter->ctx, "%s is not an ELF object\n", pakfire_file_get_path(file));
-                       r = -EINVAL;
-                       goto ERROR;
-       }
-
-       // Call the callback
-       r = callback(linter, file, elf, data);
-
-ERROR:
-       if (elf)
-               elf_end(elf);
-
-       return r;
-}
-
-static int __pakfire_linter_get_elf_type(struct pakfire_linter* linter,
-               struct pakfire_file* file, Elf* elf, void* data) {
-       GElf_Ehdr ehdr = {};
-
-       int* type = data;
-
-       // Fetch the ELF header
-       if (!gelf_getehdr(elf, &ehdr)) {
-               ERROR(linter->ctx, "Could not parse ELF header: %s\n", elf_errmsg(-1));
-               return -EINVAL;
-       }
-
-       // Store the type
-       *type = ehdr.e_type;
-
-       return 0;
-}
-
-static int pakfire_linter_get_elf_type(
-               struct pakfire_linter* linter, struct pakfire_file* file, int fd) {
-       int type = ET_NONE;
-       int r;
-
-       // Fetch the type
-       r = pakfire_linter_elf(linter, file, fd, __pakfire_linter_get_elf_type, &type);
-       if (r < 0)
-               return r;
-
-       return type;
-}
-
-static int pakfire_linter_check_pie(
-               struct pakfire_linter* linter, struct pakfire_file* file, int fd) {
-       switch (pakfire_linter_get_elf_type(linter, file, fd)) {
-               // Shared Object files are good
-               case ET_DYN:
-                       return 0;
-
-               // Everything else is bad
-               default:
-                       break;
-       }
-
-       return pakfire_linter_error(linter, "%s is not PIE", pakfire_file_get_path(file));
-}
-
 static int pakfire_linter_read_file(
                struct pakfire_linter* linter, struct pakfire_file* file, struct archive* a) {
        int fd = -EBADF;
@@ -460,17 +318,10 @@ static int pakfire_linter_payload(
                goto ERROR;
        }
 
-       // XXX TODO
-
-       // Check ELF files
-       if (pakfire_linter_file_is_elf(linter, file, fd)) {
-               // Check PIE
-               r = pakfire_linter_check_pie(linter, file, fd);
-               if (r < 0)
-                       goto ERROR;
-
-               // TODO
-       }
+       // Lint the file
+       r = pakfire_linter_file_lint(lfile);
+       if (r < 0)
+               goto ERROR;
 
 ERROR:
        if (lfile)