From: Michael Tremer Date: Thu, 24 Oct 2024 15:41:58 +0000 (+0000) Subject: FHS: Return a bitmap with any issues X-Git-Tag: 0.9.30~911 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4ef317a20796d587f89a17c98b5a131a11785b2a;p=pakfire.git FHS: Return a bitmap with any issues Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/fhs.c b/src/libpakfire/fhs.c index f4ac61a33..3bcb78bcd 100644 --- a/src/libpakfire/fhs.c +++ b/src/libpakfire/fhs.c @@ -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; } diff --git a/src/libpakfire/include/pakfire/fhs.h b/src/libpakfire/include/pakfire/fhs.h index a02d235d0..aae6b28cd 100644 --- a/src/libpakfire/include/pakfire/fhs.h +++ b/src/libpakfire/include/pakfire/fhs.h @@ -24,6 +24,15 @@ #include #include +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 */