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
{ "/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 },
{ "/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
{ "/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 },
// /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 },
{ "/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 },
// 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;
// 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
if (strcmp(check->uname, uname) != 0) {
CTX_DEBUG(ctx, "%s: uname does not match\n", path);
- return 1;
+ return PAKFIRE_FHS_UNAME_MISMATCH;
}
}
if (strcmp(check->gname, gname) != 0) {
CTX_DEBUG(ctx, "%s: gname does not match\n", path);
- return 1;
+ return PAKFIRE_FHS_GNAME_MISMATCH;
}
}
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
// 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;
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
// 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) {
}
// 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;
}