]> git.ipfire.org Git - people/stevee/pakfire.git/blobdiff - src/libpakfire/fhs.c
FHS: Drop limitation for only non-executable files in /usr/share
[people/stevee/pakfire.git] / src / libpakfire / fhs.c
index 75d3fbf82a7b81890412dc4a3d327ddff74c8006..e819b8651dcde1d24a38494d171e28f5e99c1705 100644 (file)
@@ -58,13 +58,25 @@ static const struct pakfire_fhs_check {
        { "/usr/src/**",                0,    0,   NULL,   NULL, PAKFIRE_FHS_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_MUSTNOTEXIST },
+       { "/usr/sbin/*",          S_IFDIR,    0,   NULL,   NULL, PAKFIRE_FHS_MUSTNOTEXIST },
+
+       // Permitted setuid binaries
+       { "/usr/bin/passwd",      S_IFREG, 4755, "root", "root", 0 },
+       { "/usr/bin/su",          S_IFREG, 4755, "root", "root", 0 },
+       { "/usr/bin/sudo",        S_IFREG, 4755, "root", "root", 0 },
 
        // Any files in /usr/{,s}bin must be owned by root and have 0755
        { "/usr/bin/*",           S_IFREG, 0755, "root", "root", 0 },
        { "/usr/sbin/*",          S_IFREG, 0755, "root", "root", 0 },
 
+       // Shared Libraries must be executable
+       { "/usr/lib64/*.so.*",    S_IFREG, 0755, "root", "root", 0 },
+       { "/usr/lib64/**/*.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/include: Ensure that:
        //   * All files are non-executable and belong to root
        //   * All directories have 0755 and belong to root
@@ -75,9 +87,6 @@ static const struct pakfire_fhs_check {
        { "/usr/lib/firmware/**", S_IFREG, 0644, "root", "root", 0 },
        { "/usr/lib/firmware/**", S_IFDIR, 0755, "root", "root", 0 },
 
-       // /usr/share cannot have any exectuable files
-       { "/usr/share/**",        S_IFREG,    0,   NULL,   NULL, PAKFIRE_FHS_NOEXEC },
-
        // /var
        { "/var",                 S_IFDIR, 0755, "root", "root", 0 },
        { "/var/cache",           S_IFDIR, 0755, "root", "root", 0 },
@@ -133,6 +142,11 @@ static const struct pakfire_fhs_check {
        { "/proc",                S_IFDIR, 0755, "root", "root", 0 },
        { "/proc/**",                   0,    0,   NULL,   NULL, PAKFIRE_FHS_MUSTNOTEXIST },
 
+       // root
+       { "/root",                S_IFDIR, 0700, "root", "root", 0 },
+       { "/root/.*",             S_IFREG, 0644, "root", "root", 0 },
+       { "/root/**",                   0,    0,   NULL,   NULL, PAKFIRE_FHS_MUSTNOTEXIST },
+
        // /run
        { "/run",                 S_IFDIR, 0755, "root", "root", 0 },
        { "/run/**",                    0,    0,   NULL,   NULL, PAKFIRE_FHS_MUSTNOTEXIST },
@@ -208,6 +222,32 @@ ERROR:
        return NULL;
 }
 
+static int pakfire_fhs_check_world_writable(
+               struct pakfire* pakfire, struct pakfire_file* file) {
+       // Run this check only for regular files
+       switch (pakfire_file_get_type(file)) {
+               case S_IFREG:
+                       break;
+
+               default:
+                       return 0;
+       }
+
+       // Fetch path
+       const char* path = pakfire_file_get_path(file);
+
+       // Fetch permissions
+       const mode_t perms = pakfire_file_get_perms(file);
+
+       // Check that none of the executable bits are set
+       if ((perms & (S_IWUSR|S_IWGRP|S_IWOTH)) == (S_IWUSR|S_IWGRP|S_IWOTH)) {
+               DEBUG(pakfire, "%s is world-writable\n", path);
+               return 1;
+       }
+
+       return 0;
+}
+
 static int pakfire_fhs_check_perms(struct pakfire* pakfire,
                const struct pakfire_fhs_check* check, struct pakfire_file* file) {
        // No permissions defined. Skipping check...
@@ -291,6 +331,11 @@ int pakfire_fhs_check_file(struct pakfire* pakfire, struct pakfire_file* file) {
        if (!path)
                return 1;
 
+       // Check for world-writable permissions
+       r = pakfire_fhs_check_world_writable(pakfire, file);
+       if (r)
+               return r;
+
        // Find a check
        check = pakfire_fhs_find_check(pakfire, file);
        if (!check) {