]> git.ipfire.org Git - people/stevee/pakfire.git/commitdiff
FHS: Implement checking file ownerships
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 17 Mar 2023 10:18:06 +0000 (10:18 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 17 Mar 2023 10:18:06 +0000 (10:18 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/fhs.c

index 73c258d6a62838e3428ac0033cb1c53b2d112791..4b4d3203631bb73c8932377be421846576f9be8b 100644 (file)
@@ -38,88 +38,90 @@ static const struct pakfire_fhs_check {
                PAKFIRE_FHS_MUSTNOTEXIST = (1 << 0),
        } flags;
        const mode_t mode;
+       const char* uname;
+       const char* gname;
 } pakfire_fhs_check[] = {
        // /usr
-       { "/usr",         0, S_IFDIR|0755 },
-       { "/usr/bin",     0, S_IFDIR|0755 },
-       { "/usr/include", 0, S_IFDIR|0755 },
-       { "/usr/lib",     0, S_IFDIR|0755 },
-       { "/usr/lib64",   0, S_IFDIR|0755 },
-       { "/usr/sbin",    0, S_IFDIR|0755 },
-       { "/usr/share",   0, S_IFDIR|0755 },
-       { "/usr/src",     0, S_IFDIR|0755 },
+       { "/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" },
 
        // /var
-       { "/var",         0, S_IFDIR|0755 },
-       { "/var/cache",   0, S_IFDIR|0755 },
-       { "/var/db",      0, S_IFDIR|0755 },
-       { "/var/empty",   0, S_IFDIR|0755 },
-       { "/var/lib",     0, S_IFDIR|0755 },
-       { "/var/log",     0, S_IFDIR|0755 },
-       { "/var/mail",    0, S_IFDIR|0755 },
-       { "/var/opt",     0, S_IFDIR|0755 },
-       { "/var/run",     0, S_IFLNK|0777 },
-       { "/var/spool",   0, S_IFDIR|0755 },
-       { "/var/tmp",     0, S_IFDIR|1755 },
-       { "/var/tmp/**",  PAKFIRE_FHS_MUSTNOTEXIST, 0 },
+       { "/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 },
 
        // /boot
-       { "/boot",        0, S_IFDIR|0755 },
-       { "/boot/efi",    0, S_IFDIR|0755 },
+       { "/boot",        0, S_IFDIR|0755, "root", "root" },
+       { "/boot/efi",    0, S_IFDIR|0755, "root", "root" },
 
        // /dev (nothing may exist in it)
-       { "/dev",         0, S_IFDIR|0755 },
-       { "/dev/**",      PAKFIRE_FHS_MUSTNOTEXIST, 0 },
+       { "/dev",         0, S_IFDIR|0755, "root", "root" },
+       { "/dev/**",      PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL },
 
        // /etc
-       { "/etc",         0, S_IFDIR|0755 },
+       { "/etc",         0, S_IFDIR|0755, "root", "root" },
 
        // /home
-       { "/home",        0, S_IFDIR|0755 },
-       { "/home/**",     PAKFIRE_FHS_MUSTNOTEXIST, 0 },
+       { "/home",        0, S_IFDIR|0755, "root", "root" },
+       { "/home/**",     PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL },
 
        // /opt
-       { "/opt",         0, S_IFDIR|0755 },
+       { "/opt",         0, S_IFDIR|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 },
-       { "/opt/doc",     PAKFIRE_FHS_MUSTNOTEXIST, 0 },
-       { "/opt/include", PAKFIRE_FHS_MUSTNOTEXIST, 0 },
-       { "/opt/info",    PAKFIRE_FHS_MUSTNOTEXIST, 0 },
-       { "/opt/lib",     PAKFIRE_FHS_MUSTNOTEXIST, 0 },
-       { "/opt/man",     PAKFIRE_FHS_MUSTNOTEXIST, 0 },
+       { "/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 },
 
        // /proc
-       { "/proc",        0, S_IFDIR|0755 },
-       { "/proc/**",     PAKFIRE_FHS_MUSTNOTEXIST, 0 },
+       { "/proc",        0, S_IFDIR|0755, "root", "root" },
+       { "/proc/**",     PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL },
 
        // /run
-       { "/run",         0, S_IFDIR|0755 },
+       { "/run",         0, S_IFDIR|0755, "root", "root" },
 
        // /sys
-       { "/sys",         0, S_IFDIR|0755 },
-       { "/sys/**",      PAKFIRE_FHS_MUSTNOTEXIST, 0 },
+       { "/sys",         0, S_IFDIR|0755, "root", "root" },
+       { "/sys/**",      PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL },
 
        // /tmp
-       { "/tmp",         0, S_IFDIR|1755 },
-       { "/tmp/**",      PAKFIRE_FHS_MUSTNOTEXIST, 0 },
+       { "/tmp",         0, S_IFDIR|1755, "root", "root" },
+       { "/tmp/**",      PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL },
 
        // FHS Directories
-       { "/media",       0, S_IFDIR|0755 },
-       { "/mnt",         0, S_IFDIR|0755 },
-       { "/srv",         0, S_IFDIR|0755 },
+       { "/media",       0, S_IFDIR|0755, "root", "root" },
+       { "/mnt",         0, S_IFDIR|0755, "root", "root" },
+       { "/srv",         0, S_IFDIR|0755, "root", "root" },
 
        // /bin, /sbin, /lib, and /lib64 have to be symlinks
-       { "/bin",         0, S_IFLNK|0777 },
-       { "/lib",         0, S_IFLNK|0777 },
-       { "/lib64",       0, S_IFLNK|0777 },
-       { "/sbin",        0, S_IFLNK|0777 },
+       { "/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 },
 
        // There cannot be anything else in /
-       { "/*",           PAKFIRE_FHS_MUSTNOTEXIST, 0 },
+       { "/*",           PAKFIRE_FHS_MUSTNOTEXIST, 0, NULL, NULL },
 
        // Catch all so that we won't throw an error
-       { "/**",          0, 0 },
+       { "/**",          0, 0, NULL, NULL },
 
        // Sentinel
        { NULL },
@@ -194,6 +196,38 @@ static int pakfire_fhs_check_mode(struct pakfire* pakfire,
        return 0;
 }
 
+static int pakfire_fhs_check_ownership(struct pakfire* pakfire,
+               const struct pakfire_fhs_check* check, struct pakfire_file* file) {
+       const char* path = pakfire_file_get_path(file);
+
+       // Check uname
+       if (check->uname) {
+               const char* uname = pakfire_file_get_uname(file);
+               if (!uname)
+                       return 1;
+
+               if (strcmp(check->uname, uname) != 0) {
+                       DEBUG(pakfire, "%s: uname does not match\n", path);
+                       return 1;
+               }
+       }
+
+       // Check gname
+       if (check->gname) {
+               const char* gname = pakfire_file_get_gname(file);
+               if (!gname)
+                       return 1;
+
+               if (strcmp(check->gname, gname) != 0) {
+                       DEBUG(pakfire, "%s: gname does not match\n", path);
+                       return 1;
+               }
+       }
+
+       // Pass
+       return 0;
+}
+
 int pakfire_fhs_check_file(struct pakfire* pakfire, struct pakfire_file* file) {
        const struct pakfire_fhs_check* check = NULL;
        int r;
@@ -221,6 +255,11 @@ int pakfire_fhs_check_file(struct pakfire* pakfire, struct pakfire_file* file) {
        if (r)
                return r;
 
+       // Check ownership
+       r = pakfire_fhs_check_ownership(pakfire, check, file);
+       if (r)
+               return r;
+
        // Check passed!
        return 0;
 }