const char* gname;
enum pakfire_fhs_check_flags {
PAKFIRE_FHS_MUSTNOTEXIST = (1 << 0),
+ PAKFIRE_FHS_NOEXEC = (1 << 1),
} flags;
} pakfire_fhs_check[] = {
// /usr
{ "/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 },
return 0;
}
+static int pakfire_fhs_check_noexec(struct pakfire* pakfire,
+ 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))
+ 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_IXUSR|S_IXGRP|S_IXOTH)) {
+ DEBUG(pakfire, "%s must not be executable\n", path);
+ return 1;
+ }
+
+ return 0;
+}
+
int pakfire_fhs_check_file(struct pakfire* pakfire, struct pakfire_file* file) {
const struct pakfire_fhs_check* check = NULL;
int r;
if (r)
return r;
+ // Check for PAKFIRE_FHS_NOEXEC
+ r = pakfire_fhs_check_noexec(pakfire, check, file);
+ if (r)
+ return r;
+
// Check passed!
return 0;
}