From 84a9a7b701b48acb17a25df5141758e5023da72f Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Fri, 17 Mar 2023 10:37:25 +0000 Subject: [PATCH] FHS: Implement being able to check for file type This allows us a more granular filtering Signed-off-by: Michael Tremer --- src/libpakfire/fhs.c | 162 +++++++++++++++++++++---------------------- 1 file changed, 79 insertions(+), 83 deletions(-) diff --git a/src/libpakfire/fhs.c b/src/libpakfire/fhs.c index 979bca7a5..f82d80349 100644 --- a/src/libpakfire/fhs.c +++ b/src/libpakfire/fhs.c @@ -34,110 +34,123 @@ */ static const struct pakfire_fhs_check { const char* path; + const mode_t type; enum pakfire_fhs_check_flags { PAKFIRE_FHS_MUSTNOTEXIST = (1 << 0), } flags; - const mode_t mode; + const mode_t perms; const char* uname; const char* gname; } pakfire_fhs_check[] = { // /usr - { "/usr", 0, S_IFDIR|0755, "root", "root" }, - { "/usr/bin", 0, S_IFDIR|0755, "root", "root" }, - { "/usr/include", 0, S_IFDIR|0755, "root", "root" }, - { "/usr/lib", 0, S_IFDIR|0755, "root", "root" }, - { "/usr/lib64", 0, S_IFDIR|0755, "root", "root" }, - { "/usr/sbin", 0, S_IFDIR|0755, "root", "root" }, - { "/usr/share", 0, S_IFDIR|0755, "root", "root" }, - { "/usr/src", 0, S_IFDIR|0755, "root", "root" }, + { "/usr", S_IFDIR, 0, 0755, "root", "root" }, + { "/usr/bin", S_IFDIR, 0, 0755, "root", "root" }, + { "/usr/include", S_IFDIR, 0, 0755, "root", "root" }, + { "/usr/lib", S_IFDIR, 0, 0755, "root", "root" }, + { "/usr/lib64", S_IFDIR, 0, 0755, "root", "root" }, + { "/usr/sbin", S_IFDIR, 0, 0755, "root", "root" }, + { "/usr/share", S_IFDIR, 0, 0755, "root", "root" }, + { "/usr/src", S_IFDIR, 0, 0755, "root", "root" }, // Allow no further files in /usr & /usr/src - { "/usr/*", PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, - { "/usr/src/**", PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, + { "/usr/*", 0, PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, + { "/usr/src/**", 0, PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, // /var - { "/var", 0, S_IFDIR|0755, "root", "root" }, - { "/var/cache", 0, S_IFDIR|0755, "root", "root" }, - { "/var/db", 0, S_IFDIR|0755, "root", "root" }, - { "/var/empty", 0, S_IFDIR|0755, "root", "root" }, - { "/var/lib", 0, S_IFDIR|0755, "root", "root" }, - { "/var/log", 0, S_IFDIR|0755, "root", "root" }, - { "/var/mail", 0, S_IFDIR|0755, "root", "root" }, - { "/var/opt", 0, S_IFDIR|0755, "root", "root" }, - { "/var/run", 0, S_IFLNK|0777, "root", "root" }, - { "/var/spool", 0, S_IFDIR|0755, "root", "root" }, - { "/var/tmp", 0, S_IFDIR|1755, "root", "root" }, - { "/var/tmp/**", PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, + { "/var", S_IFDIR, 0, 0755, "root", "root" }, + { "/var/cache", S_IFDIR, 0, 0755, "root", "root" }, + { "/var/db", S_IFDIR, 0, 0755, "root", "root" }, + { "/var/empty", S_IFDIR, 0, 0755, "root", "root" }, + { "/var/lib", S_IFDIR, 0, 0755, "root", "root" }, + { "/var/log", S_IFDIR, 0, 0755, "root", "root" }, + { "/var/mail", S_IFDIR, 0, 0755, "root", "root" }, + { "/var/opt", S_IFDIR, 0, 0755, "root", "root" }, + { "/var/run", S_IFLNK, 0, 0755, "root", "root" }, + { "/var/spool", S_IFDIR, 0, 0755, "root", "root" }, + { "/var/tmp", S_IFDIR, 0, 0755, "root", "root" }, + { "/var/tmp/**", 0, PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, // /boot - { "/boot", 0, S_IFDIR|0755, "root", "root" }, - { "/boot/efi", 0, S_IFDIR|0755, "root", "root" }, + { "/boot", S_IFDIR, 0, 0755, "root", "root" }, + { "/boot/efi", S_IFDIR, 0, 0755, "root", "root" }, // /dev (nothing may exist in it) - { "/dev", 0, S_IFDIR|0755, "root", "root" }, - { "/dev/**", PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, + { "/dev", S_IFDIR, 0, 0755, "root", "root" }, + { "/dev/**", 0, PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, // /etc - { "/etc", 0, S_IFDIR|0755, "root", "root" }, + { "/etc", S_IFDIR, 0, 0755, "root", "root" }, // /home - { "/home", 0, S_IFDIR|0755, "root", "root" }, - { "/home/**", PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, + { "/home", S_IFDIR, 0, 0755, "root", "root" }, + { "/home/**", 0, PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, // /opt - { "/opt", 0, S_IFDIR|0755, "root", "root" }, + { "/opt", S_IFDIR, 0, 0755, "root", "root" }, // These directories belong to the "local administrator" // https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch03s13.html - { "/opt/bin", PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, - { "/opt/doc", PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, - { "/opt/include", PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, - { "/opt/info", PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, - { "/opt/lib", PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, - { "/opt/man", PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, + { "/opt/bin", 0, PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, + { "/opt/doc", 0, PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, + { "/opt/include", 0, PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, + { "/opt/info", 0, PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, + { "/opt/lib", 0, PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, + { "/opt/man", 0, PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, // /proc - { "/proc", 0, S_IFDIR|0755, "root", "root" }, - { "/proc/**", PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, + { "/proc", S_IFDIR, 0, 0755, "root", "root" }, + { "/proc/**", 0, PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, // /run - { "/run", 0, S_IFDIR|0755, "root", "root" }, + { "/run", S_IFDIR, 0, 0755, "root", "root" }, + { "/run/**", 0, PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, // /sys - { "/sys", 0, S_IFDIR|0755, "root", "root" }, - { "/sys/**", PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, + { "/sys", S_IFDIR, 0, 0755, "root", "root" }, + { "/sys/**", 0, PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, // /tmp - { "/tmp", 0, S_IFDIR|1755, "root", "root" }, - { "/tmp/**", PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, + { "/tmp", S_IFDIR, 0, 1755, "root", "root" }, + { "/tmp/**", 0, PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, // FHS Directories - { "/media", 0, S_IFDIR|0755, "root", "root" }, - { "/mnt", 0, S_IFDIR|0755, "root", "root" }, - { "/srv", 0, S_IFDIR|0755, "root", "root" }, + { "/media", S_IFDIR, 0, 0755, "root", "root" }, + { "/mnt", S_IFDIR, 0, 0755, "root", "root" }, + { "/srv", S_IFDIR, 0, 0755, "root", "root" }, // /bin, /sbin, /lib, and /lib64 have to be symlinks - { "/bin", 0, S_IFLNK|0777, NULL, NULL }, - { "/lib", 0, S_IFLNK|0777, NULL, NULL }, - { "/lib64", 0, S_IFLNK|0777, NULL, NULL }, - { "/sbin", 0, S_IFLNK|0777, NULL, NULL }, + { "/bin", S_IFLNK, 0, 0777, NULL, NULL }, + { "/lib", S_IFLNK, 0, 0777, NULL, NULL }, + { "/lib64", S_IFLNK, 0, 0777, NULL, NULL }, + { "/sbin", S_IFLNK, 0, 0777, NULL, NULL }, // There cannot be anything else in / - { "/*", PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, + { "/*", 0, PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL }, // Catch all so that we won't throw an error - { "/**", 0, 0, NULL, NULL }, + { "/**", 0, 0, 0, NULL, NULL }, // Sentinel { NULL }, }; static const struct pakfire_fhs_check* pakfire_fhs_find_check( - struct pakfire* pakfire, const char* path) { + struct pakfire* pakfire, struct pakfire_file* file) { const struct pakfire_fhs_check* check = NULL; int r; + // Fetch the file type + const mode_t type = pakfire_file_get_type(file); + + // Fetch the path + const char* path = pakfire_file_get_path(file); + // Walk through all possible checks for (check = pakfire_fhs_check; check->path; check++) { + // Skip this check if the filetype doesn't match + if (check->type && check->type != type) + continue; + + // Check path r = pakfire_path_match(check->path, path); switch (r) { // No match @@ -162,38 +175,21 @@ ERROR: return NULL; } -static int pakfire_fhs_check_mode(struct pakfire* pakfire, +static int pakfire_fhs_check_perms(struct pakfire* pakfire, const struct pakfire_fhs_check* check, struct pakfire_file* file) { - // No mode defined. Skipping check... - if (!check->mode) + // No permissions defined. Skipping check... + if (!check->perms) return 0; const char* path = pakfire_file_get_path(file); - // Compare mode - const mode_t mode = pakfire_file_get_mode(file); - - // Check if mode matches straight away - if (check->mode == mode) - return 0; - - const mode_t check_type = check->mode & S_IFMT; - const mode_t check_perms = check->mode & ~S_IFMT; + // Fetch perms + const mode_t perms = pakfire_file_get_perms(file); - // Check the file type - if (check_type) { - if ((mode_t)pakfire_file_get_type(file) != check_type) { - ERROR(pakfire, "%s: Filetype does not match\n", path); - return 1; - } - } - - // Check the file perms - if (check_perms) { - if (pakfire_file_get_perms(file) != check_perms) { - ERROR(pakfire, "%s: Permissions do not match\n", path); - return 1; - } + // Check if they match + if (check->perms != perms) { + DEBUG(pakfire, "%s: Permissions do not match\n", path); + return 1; } // Check passed @@ -242,7 +238,7 @@ int pakfire_fhs_check_file(struct pakfire* pakfire, struct pakfire_file* file) { return 1; // Find a check - check = pakfire_fhs_find_check(pakfire, path); + check = pakfire_fhs_find_check(pakfire, file); if (!check) { ERROR(pakfire, "Could not match file %s: %m\n", path); return 1; @@ -254,8 +250,8 @@ int pakfire_fhs_check_file(struct pakfire* pakfire, struct pakfire_file* file) { return 1; } - // Check type & mode - r = pakfire_fhs_check_mode(pakfire, check, file); + // Check permissions + r = pakfire_fhs_check_perms(pakfire, check, file); if (r) return r; -- 2.39.5