]> git.ipfire.org Git - pakfire.git/commitdiff
FHS: Return a bitmap with any issues
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 24 Oct 2024 15:41:58 +0000 (15:41 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 24 Oct 2024 15:41:58 +0000 (15:41 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/fhs.c
src/libpakfire/include/pakfire/fhs.h

index f4ac61a3374409c78a040d57d6bbdb3e00d8f9fd..3bcb78bcded337f325a9be11a3014d385528dc7d 100644 (file)
@@ -40,8 +40,8 @@ static const struct pakfire_fhs_check {
        const char* uname;
        const char* gname;
        enum pakfire_fhs_check_flags {
-               PAKFIRE_FHS_MUSTNOTEXIST = (1 << 0),
-               PAKFIRE_FHS_NOEXEC       = (1 << 1),
+               PAKFIRE_FHS_CHECK_MUSTNOTEXIST = (1 << 0),
+               PAKFIRE_FHS_CHECK_NOEXEC       = (1 << 1),
        } flags;
 } pakfire_fhs_check[] = {
        // /usr
@@ -56,15 +56,15 @@ static const struct pakfire_fhs_check {
        { "/usr/src/kernels",     S_IFDIR, 0755, "root", "root", 0 },
 
        // Allow no further files in /usr
-       { "/usr/*",                     0,    0,   NULL,   NULL, PAKFIRE_FHS_MUSTNOTEXIST },
+       { "/usr/*",                     0,    0,   NULL,   NULL, PAKFIRE_FHS_CHECK_MUSTNOTEXIST },
 
        // Allow no files in /usr/src except some kernel source
        { "/usr/src/kernels/**",        0,    0, "root", "root", 0 },
-       { "/usr/src/**",                0,    0,   NULL,   NULL, PAKFIRE_FHS_MUSTNOTEXIST },
+       { "/usr/src/**",                0,    0,   NULL,   NULL, PAKFIRE_FHS_CHECK_MUSTNOTEXIST },
 
        // There cannot be any subdirectories in /usr/bin & /usr/sbin
-       { "/usr/bin/*",           S_IFDIR,    0,   NULL,   NULL, PAKFIRE_FHS_MUSTNOTEXIST },
-       { "/usr/sbin/*",          S_IFDIR,    0,   NULL,   NULL, PAKFIRE_FHS_MUSTNOTEXIST },
+       { "/usr/bin/*",           S_IFDIR,    0,   NULL,   NULL, PAKFIRE_FHS_CHECK_MUSTNOTEXIST },
+       { "/usr/sbin/*",          S_IFDIR,    0,   NULL,   NULL, PAKFIRE_FHS_CHECK_MUSTNOTEXIST },
 
        // Permitted setuid binaries
        { "/usr/bin/gpasswd",     S_IFREG, S_ISUID|0755, "root", "root", 0 },
@@ -85,7 +85,7 @@ static const struct pakfire_fhs_check {
        { "/usr/lib/ld-*.so.*",   S_IFREG, 0755, "root", "root", 0 },
 
        // Shared Libraries must not exist in /usr/lib
-       { "/usr/lib/*.so*",       S_IFREG,    0,   NULL,   NULL, PAKFIRE_FHS_MUSTNOTEXIST },
+       { "/usr/lib/*.so*",       S_IFREG,    0,   NULL,   NULL, PAKFIRE_FHS_CHECK_MUSTNOTEXIST },
 
        // /usr/include: Ensure that:
        //   * All files are non-executable and belong to root
@@ -113,12 +113,12 @@ static const struct pakfire_fhs_check {
        { "/var/tmp",             S_IFDIR, 0755,  "root", "root", 0 },
 
        // Do not allow any subdirectories in /var
-       { "/var/*",                     0,    0,   NULL,   NULL, PAKFIRE_FHS_MUSTNOTEXIST },
-       { "/var/empty/**",              0,    0,   NULL,   NULL, PAKFIRE_FHS_MUSTNOTEXIST },
-       { "/var/tmp/**",                0,    0,   NULL,   NULL, PAKFIRE_FHS_MUSTNOTEXIST },
+       { "/var/*",                     0,    0,   NULL,   NULL, PAKFIRE_FHS_CHECK_MUSTNOTEXIST },
+       { "/var/empty/**",              0,    0,   NULL,   NULL, PAKFIRE_FHS_CHECK_MUSTNOTEXIST },
+       { "/var/tmp/**",                0,    0,   NULL,   NULL, PAKFIRE_FHS_CHECK_MUSTNOTEXIST },
 
        // No files in /var may be executable
-       { "/var/**",              S_IFREG,    0,   NULL,   NULL, PAKFIRE_FHS_NOEXEC },
+       { "/var/**",              S_IFREG,    0,   NULL,   NULL, PAKFIRE_FHS_CHECK_NOEXEC },
 
        // /boot
        { "/boot",                S_IFDIR, 0755, "root", "root", 0 },
@@ -130,46 +130,46 @@ static const struct pakfire_fhs_check {
 
        // /dev (nothing may exist in it)
        { "/dev",                 S_IFDIR, 0755, "root", "root", 0 },
-       { "/dev/**",                    0,    0,   NULL,   NULL, PAKFIRE_FHS_MUSTNOTEXIST },
+       { "/dev/**",                    0,    0,   NULL,   NULL, PAKFIRE_FHS_CHECK_MUSTNOTEXIST },
 
        // /etc
        { "/etc",                 S_IFDIR, 0755, "root", "root", 0 },
 
        // /home
        { "/home",                S_IFDIR, 0755, "root", "root", 0 },
-       { "/home/**",                   0,    0,   NULL,   NULL, PAKFIRE_FHS_MUSTNOTEXIST },
+       { "/home/**",                   0,    0,   NULL,   NULL, PAKFIRE_FHS_CHECK_MUSTNOTEXIST },
 
        // /opt
        { "/opt",                 S_IFDIR, 0755, "root", "root", 0 },
        // These directories belong to the "local administrator"
        // https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch03s13.html
-       { "/opt/bin",                   0,    0,   NULL,   NULL, PAKFIRE_FHS_MUSTNOTEXIST },
-       { "/opt/doc",                   0,    0,   NULL,   NULL, PAKFIRE_FHS_MUSTNOTEXIST },
-       { "/opt/include",               0,    0,   NULL,   NULL, PAKFIRE_FHS_MUSTNOTEXIST },
-       { "/opt/info",                  0,    0,   NULL,   NULL, PAKFIRE_FHS_MUSTNOTEXIST },
-       { "/opt/lib",                   0,    0,   NULL,   NULL, PAKFIRE_FHS_MUSTNOTEXIST },
-       { "/opt/man",                   0,    0,   NULL,   NULL, PAKFIRE_FHS_MUSTNOTEXIST },
+       { "/opt/bin",                   0,    0,   NULL,   NULL, PAKFIRE_FHS_CHECK_MUSTNOTEXIST },
+       { "/opt/doc",                   0,    0,   NULL,   NULL, PAKFIRE_FHS_CHECK_MUSTNOTEXIST },
+       { "/opt/include",               0,    0,   NULL,   NULL, PAKFIRE_FHS_CHECK_MUSTNOTEXIST },
+       { "/opt/info",                  0,    0,   NULL,   NULL, PAKFIRE_FHS_CHECK_MUSTNOTEXIST },
+       { "/opt/lib",                   0,    0,   NULL,   NULL, PAKFIRE_FHS_CHECK_MUSTNOTEXIST },
+       { "/opt/man",                   0,    0,   NULL,   NULL, PAKFIRE_FHS_CHECK_MUSTNOTEXIST },
 
        // /proc
        { "/proc",                S_IFDIR, 0755, "root", "root", 0 },
-       { "/proc/**",                   0,    0,   NULL,   NULL, PAKFIRE_FHS_MUSTNOTEXIST },
+       { "/proc/**",                   0,    0,   NULL,   NULL, PAKFIRE_FHS_CHECK_MUSTNOTEXIST },
 
        // root
        { "/root",                S_IFDIR, 0700, "root", "root", 0 },
        { "/root/.*",             S_IFREG, 0644, "root", "root", 0 },
-       { "/root/**",                   0,    0,   NULL,   NULL, PAKFIRE_FHS_MUSTNOTEXIST },
+       { "/root/**",                   0,    0,   NULL,   NULL, PAKFIRE_FHS_CHECK_MUSTNOTEXIST },
 
        // /run
        { "/run",                 S_IFDIR, 0755, "root", "root", 0 },
-       { "/run/**",                    0,    0,   NULL,   NULL, PAKFIRE_FHS_MUSTNOTEXIST },
+       { "/run/**",                    0,    0,   NULL,   NULL, PAKFIRE_FHS_CHECK_MUSTNOTEXIST },
 
        // /sys
        { "/sys",                 S_IFDIR, 0755, "root", "root", 0 },
-       { "/sys/**",                    0,    0,   NULL,   NULL, PAKFIRE_FHS_MUSTNOTEXIST },
+       { "/sys/**",                    0,    0,   NULL,   NULL, PAKFIRE_FHS_CHECK_MUSTNOTEXIST },
 
        // /tmp
        { "/tmp",                 S_IFDIR, 01755, "root", "root", 0 },
-       { "/tmp/**",                    0,    0,   NULL,   NULL, PAKFIRE_FHS_MUSTNOTEXIST },
+       { "/tmp/**",                    0,    0,   NULL,   NULL, PAKFIRE_FHS_CHECK_MUSTNOTEXIST },
 
        // FHS Directories
        { "/media",               S_IFDIR, 0755, "root", "root", 0 },
@@ -183,7 +183,7 @@ static const struct pakfire_fhs_check {
        { "/sbin",                S_IFLNK, 0777,   NULL,   NULL, 0 },
 
        // There cannot be anything else in /
-       { "/*",                         0,    0,   NULL,   NULL, PAKFIRE_FHS_MUSTNOTEXIST },
+       { "/*",                         0,    0,   NULL,   NULL, PAKFIRE_FHS_CHECK_MUSTNOTEXIST },
 
        // Catch all so that we won't throw an error
        { "/**",                        0,    0,   NULL,   NULL, 0 },
@@ -254,7 +254,7 @@ static int pakfire_fhs_check_world_writable(
        // Check that none of the executable bits are set
        if ((perms & (S_IWUSR|S_IWGRP|S_IWOTH)) == (S_IWUSR|S_IWGRP|S_IWOTH)) {
                CTX_DEBUG(ctx, "%s is world-writable\n", path);
-               return 1;
+               return PAKFIRE_FHS_WORLDWRITABLE;
        }
 
        return 0;
@@ -274,7 +274,7 @@ static int pakfire_fhs_check_perms(struct pakfire_ctx* ctx,
        // Check if they match
        if (check->perms != perms) {
                CTX_DEBUG(ctx, "%s: Permissions do not match\n", path);
-               return 1;
+               return PAKFIRE_FHS_PERMS_MISMATCH;
        }
 
        // Check passed
@@ -293,7 +293,7 @@ static int pakfire_fhs_check_ownership(struct pakfire_ctx* ctx,
 
                if (strcmp(check->uname, uname) != 0) {
                        CTX_DEBUG(ctx, "%s: uname does not match\n", path);
-                       return 1;
+                       return PAKFIRE_FHS_UNAME_MISMATCH;
                }
        }
 
@@ -305,7 +305,7 @@ static int pakfire_fhs_check_ownership(struct pakfire_ctx* ctx,
 
                if (strcmp(check->gname, gname) != 0) {
                        CTX_DEBUG(ctx, "%s: gname does not match\n", path);
-                       return 1;
+                       return PAKFIRE_FHS_GNAME_MISMATCH;
                }
        }
 
@@ -315,8 +315,8 @@ static int pakfire_fhs_check_ownership(struct pakfire_ctx* ctx,
 
 static int pakfire_fhs_check_noexec(struct pakfire_ctx* ctx,
                const struct pakfire_fhs_check* check, struct pakfire_file* file) {
-       // Skip this check if PAKFIRE_FHS_NOEXEC is not set
-       if (!(check->flags & PAKFIRE_FHS_NOEXEC))
+       // Skip this check if PAKFIRE_FHS_CHECK_NOEXEC is not set
+       if (!(check->flags & PAKFIRE_FHS_CHECK_NOEXEC))
                return 0;
 
        // Fetch path
@@ -328,7 +328,7 @@ static int pakfire_fhs_check_noexec(struct pakfire_ctx* ctx,
        // Check that none of the executable bits are set
        if (perms & (S_IXUSR|S_IXGRP|S_IXOTH)) {
                CTX_DEBUG(ctx, "%s must not be executable\n", path);
-               return 1;
+               return PAKFIRE_FHS_NOEXEC;
        }
 
        return 0;
@@ -336,6 +336,7 @@ static int pakfire_fhs_check_noexec(struct pakfire_ctx* ctx,
 
 int pakfire_fhs_check_file(struct pakfire_ctx* ctx, struct pakfire_file* file) {
        const struct pakfire_fhs_check* check = NULL;
+       int status = 0;
        int r;
 
        // Get the file path
@@ -345,9 +346,12 @@ int pakfire_fhs_check_file(struct pakfire_ctx* ctx, struct pakfire_file* file) {
 
        // Check for world-writable permissions
        r = pakfire_fhs_check_world_writable(ctx, file);
-       if (r)
+       if (r < 0)
                return r;
 
+       // Update status
+       status |= r;
+
        // Find a check
        check = pakfire_fhs_find_check(ctx, file);
        if (!check) {
@@ -356,26 +360,34 @@ int pakfire_fhs_check_file(struct pakfire_ctx* ctx, struct pakfire_file* file) {
        }
 
        // Should this file exist at all?
-       if (check->flags & PAKFIRE_FHS_MUSTNOTEXIST) {
+       if (check->flags & PAKFIRE_FHS_CHECK_MUSTNOTEXIST) {
                CTX_DEBUG(ctx, "%s must not exist here\n", path);
-               return 1;
+               return PAKFIRE_FHS_MUSTNOTEXIST;
        }
 
        // Check permissions
        r = pakfire_fhs_check_perms(ctx, check, file);
-       if (r)
+       if (r < 0)
                return r;
 
+       // Update status
+       status |= r;
+
        // Check ownership
        r = pakfire_fhs_check_ownership(ctx, check, file);
-       if (r)
+       if (r < 0)
                return r;
 
-       // Check for PAKFIRE_FHS_NOEXEC
+       // Update status
+       status |= r;
+
+       // Check for PAKFIRE_FHS_CHECK_NOEXEC
        r = pakfire_fhs_check_noexec(ctx, check, file);
        if (r < 0)
                return r;
 
-       // Check passed!
-       return 0;
+       // Update status
+       status |= r;
+
+       return status;
 }
index a02d235d07d77f80ce545a15191203fc7a7a7119..aae6b28cd497c44a50ee01c38203c0e64c59c8ed 100644 (file)
 #include <pakfire/file.h>
 #include <pakfire/pakfire.h>
 
+enum pakfire_fhs_status {
+       PAKFIRE_FHS_MUSTNOTEXIST   = (1 << 0),
+       PAKFIRE_FHS_UNAME_MISMATCH = (1 << 1),
+       PAKFIRE_FHS_GNAME_MISMATCH = (1 << 2),
+       PAKFIRE_FHS_PERMS_MISMATCH = (1 << 3),
+       PAKFIRE_FHS_WORLDWRITABLE  = (1 << 4),
+       PAKFIRE_FHS_NOEXEC         = (1 << 5),
+};
+
 int pakfire_fhs_check_file(struct pakfire_ctx* ctx, struct pakfire_file* file);
 
 #endif /* PAKFIRE_FHS_H */