]> git.ipfire.org Git - pakfire.git/commitdiff
FHS: Implement being able to check for file type
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 17 Mar 2023 10:37:25 +0000 (10:37 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 17 Mar 2023 10:37:25 +0000 (10:37 +0000)
This allows us a more granular filtering

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/fhs.c

index 979bca7a5b56c4bf984839dca14b27eca7dae6de..f82d80349c4aa2c98e65dd86c6027c05481a0c79 100644 (file)
 */
 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;