From 33ded70da613fe7af4390810cfe9b3f877828bb7 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Sat, 26 Oct 2024 11:46:39 +0000 Subject: [PATCH] linter: Move RPATH check Signed-off-by: Michael Tremer --- src/libpakfire/file.c | 76 --------------------------------- src/libpakfire/linter-file.c | 81 ++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 76 deletions(-) diff --git a/src/libpakfire/file.c b/src/libpakfire/file.c index 6b229c576..d21dd7b1a 100644 --- a/src/libpakfire/file.c +++ b/src/libpakfire/file.c @@ -2018,77 +2018,6 @@ static int pakfire_file_check_debuginfo(struct pakfire_file* file) { return pakfire_file_open_elf(file, __pakfire_file_check_debuginfo, NULL); } -/* - RPATH/RUNPATH -*/ -static int __pakfire_file_process_runpath(struct pakfire_file* file, - Elf* elf, const GElf_Shdr* shdr, const GElf_Dyn* dyn, void* data) { - const char* value = NULL; - const char* runpath = NULL; - char buffer[PATH_MAX]; - char* p = NULL; - int r; - - switch (dyn->d_tag) { - case DT_RUNPATH: - case DT_RPATH: - // Fetch the value - value = elf_strptr(elf, shdr->sh_link, dyn->d_un.d_val); - if (!value) - return 1; - - DEBUG(file->ctx, "%s has a RUNPATH: %s\n", - pakfire_file_get_path(file), value); - - // Copy the value into a buffer we can modify - r = pakfire_string_set(buffer, value); - if (r) - return r; - - // Split the value by : - runpath = strtok_r(buffer, ":", &p); - - // Iterate over all elements - while (runpath) { - ERROR(file->ctx, "Checking RUNPATH %s\n", runpath); - - // We do not allow any relative RUNPATHs - if (pakfire_path_match(runpath, "**/../**")) - goto RUNPATH_DENIED; - - // We allow /usr/lib64 as libtool seems to link it in quite a lot - if (pakfire_path_match("/usr/lib64", runpath)) - goto RUNPATH_PERMITTED; - - // We allow any subdirectories of /usr/lib64 - if (pakfire_path_match( "/usr/lib64/**", runpath)) - goto RUNPATH_PERMITTED; - -RUNPATH_DENIED: - // If we make it here, this check has failed - file->issues |= PAKFIRE_FILE_HAS_RUNPATH; - break; - -RUNPATH_PERMITTED: - // Move on to the next RUNPATH - runpath = strtok_r(NULL, ":", &p); - } - - default: - break; - } - - return 0; -} - -static int __pakfire_file_check_runpath(struct pakfire_file* file, Elf* elf, void* data) { - return pakfire_file_elf_dyn_walk(file, elf, __pakfire_file_process_runpath, data); -} - -static int pakfire_file_check_runpath(struct pakfire_file* file) { - return pakfire_file_open_elf(file, __pakfire_file_check_runpath, NULL); -} - static int pakfire_file_get_script_interpreter(struct pakfire_file* file, char** interpreter) { FILE* f = NULL; char shebang[1024]; @@ -2605,11 +2534,6 @@ int pakfire_file_check(struct pakfire_file* file, int* issues) { if (r) return r; - // Check for RUNPATH - r = pakfire_file_check_runpath(file); - if (r) - return r; - // Check CF protection r = pakfire_file_check_cf_protection(file); if (r) diff --git a/src/libpakfire/linter-file.c b/src/libpakfire/linter-file.c index 1834a795e..7087aaf77 100644 --- a/src/libpakfire/linter-file.c +++ b/src/libpakfire/linter-file.c @@ -29,6 +29,7 @@ #include #include #include +#include struct pakfire_linter_file { struct pakfire_ctx* ctx; @@ -518,6 +519,81 @@ static int pakfire_linter_file_check_relro(struct pakfire_linter_file* lfile) { return pakfire_linter_file_elf(lfile, __pakfire_linter_file_check_relro, NULL); } +/* + RPATH/RUNPATH +*/ +static int __pakfire_linter_file_process_runpath(struct pakfire_linter_file* lfile, + Elf* elf, const GElf_Shdr* shdr, const GElf_Dyn* dyn, void* data) { + const char* value = NULL; + const char* runpath = NULL; + char buffer[PATH_MAX]; + char* p = NULL; + int r; + + switch (dyn->d_tag) { + case DT_RUNPATH: + case DT_RPATH: + // Fetch the value + value = elf_strptr(elf, shdr->sh_link, dyn->d_un.d_val); + if (!value) + return 1; + + DEBUG(lfile->ctx, "%s has a RUNPATH: %s\n", lfile->path, value); + + // Copy the value into a buffer we can modify + r = pakfire_string_set(buffer, value); + if (r < 0) + return r; + + // Split the value by : + runpath = strtok_r(buffer, ":", &p); + + // Iterate over all elements + while (runpath) { + ERROR(lfile->ctx, "Checking RUNPATH %s\n", runpath); + + // We do not allow any relative RUNPATHs + if (pakfire_path_match(runpath, "**/../**")) + goto RUNPATH_DENIED; + + // We allow /usr/lib64 as libtool seems to link it in quite a lot + if (pakfire_path_match("/usr/lib64", runpath)) + goto RUNPATH_PERMITTED; + + // We allow any subdirectories of /usr/lib64 + if (pakfire_path_match( "/usr/lib64/**", runpath)) + goto RUNPATH_PERMITTED; + +RUNPATH_DENIED: + // If we make it here, this check has failed + r = pakfire_linter_file_error(lfile, "Has illegal RPATH/RUNPATH %s", runpath); + if (r < 0) + return r; + + break; + +RUNPATH_PERMITTED: + // Move on to the next RUNPATH + runpath = strtok_r(NULL, ":", &p); + } + + default: + break; + } + + return 0; +} + +static int __pakfire_linter_file_check_runpath( + struct pakfire_linter_file* lfile, Elf* elf, void* data) { + return pakfire_linter_file_elf_dyn_walk( + lfile, elf, __pakfire_linter_file_process_runpath, data); +} + +static int pakfire_linter_file_check_runpath(struct pakfire_linter_file* lfile) { + return pakfire_linter_file_elf(lfile, __pakfire_linter_file_check_runpath, NULL); +} + int pakfire_linter_file_lint(struct pakfire_linter_file* lfile) { int r = 0; @@ -554,6 +630,11 @@ int pakfire_linter_file_lint(struct pakfire_linter_file* lfile) { r = pakfire_linter_file_check_relro(lfile); if (r < 0) return r; + + // Check RPATH/RUNPATH + r = pakfire_linter_file_check_runpath(lfile); + if (r < 0) + return r; } return 0; -- 2.39.5