Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GCC 14.2.0 support #2133

Merged
merged 4 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM ghcr.io/pi-hole/ftl-build:v2.9 AS builder
FROM ghcr.io/pi-hole/ftl-build:v2.10 AS builder

WORKDIR /app

Expand Down
99 changes: 61 additions & 38 deletions src/capabilities.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,30 @@
static const unsigned int capabilityIDs[] = { CAP_CHOWN , CAP_DAC_OVERRIDE , CAP_DAC_READ_SEARCH , CAP_FOWNER , CAP_FSETID , CAP_KILL , CAP_SETGID , CAP_SETUID , CAP_SETPCAP , CAP_LINUX_IMMUTABLE , CAP_NET_BIND_SERVICE , CAP_NET_BROADCAST , CAP_NET_ADMIN , CAP_NET_RAW , CAP_IPC_LOCK , CAP_IPC_OWNER , CAP_SYS_MODULE , CAP_SYS_RAWIO , CAP_SYS_CHROOT , CAP_SYS_PTRACE , CAP_SYS_PACCT , CAP_SYS_ADMIN , CAP_SYS_BOOT , CAP_SYS_NICE , CAP_SYS_RESOURCE , CAP_SYS_TIME , CAP_SYS_TTY_CONFIG , CAP_MKNOD , CAP_LEASE , CAP_AUDIT_WRITE , CAP_AUDIT_CONTROL , CAP_SETFCAP };
static const char* capabilityNames[] = {"CAP_CHOWN", "CAP_DAC_OVERRIDE", "CAP_DAC_READ_SEARCH", "CAP_FOWNER", "CAP_FSETID", "CAP_KILL", "CAP_SETGID", "CAP_SETUID", "CAP_SETPCAP", "CAP_LINUX_IMMUTABLE", "CAP_NET_BIND_SERVICE", "CAP_NET_BROADCAST", "CAP_NET_ADMIN", "CAP_NET_RAW", "CAP_IPC_LOCK", "CAP_IPC_OWNER", "CAP_SYS_MODULE", "CAP_SYS_RAWIO", "CAP_SYS_CHROOT", "CAP_SYS_PTRACE", "CAP_SYS_PACCT", "CAP_SYS_ADMIN", "CAP_SYS_BOOT", "CAP_SYS_NICE", "CAP_SYS_RESOURCE", "CAP_SYS_TIME", "CAP_SYS_TTY_CONFIG", "CAP_MKNOD", "CAP_LEASE", "CAP_AUDIT_WRITE", "CAP_AUDIT_CONTROL", "CAP_SETFCAP"};

bool check_capability(const unsigned int cap)
/**
* @brief Retrieves the capabilities of the current process.
*
* This function determines the capabilities version used by the current kernel
* and retrieves the current capabilities of the process.
*
* @param data Pointer to a cap_user_data_t structure where the capabilities
* will be stored. The memory for this structure is allocated within
* the function and should be freed by the caller.
*/
static bool get_caps(cap_user_data_t *data)
{
// First assume header version 1
int capsize = 1; // VFS_CAP_U32_1
cap_user_data_t data = NULL;
cap_user_header_t hdr = calloc(sizeof(*hdr), capsize);
cap_user_header_t hdr = calloc(1, sizeof(*hdr));

// Determine capabilities version used by the current kernel
capget(hdr, NULL);
if(capget(hdr, NULL) != 0)
{
log_err("Failed to retrieve capabilities header: %s", strerror(errno));
free(hdr);
return false;
}

// Check version
// Get size of capabilities
int capsize = 1; // VFS_CAP_U32_1
if (hdr->version != LINUX_CAPABILITY_VERSION_1)
{
// If unknown version, use largest supported version (3)
Expand All @@ -48,49 +61,60 @@ bool check_capability(const unsigned int cap)
}

// Get current capabilities
data = calloc(sizeof(*data), capsize);
capget(hdr, data);
*data = calloc(capsize, sizeof(**data));
if(capget(hdr, *data) != 0)
{
log_err("Failed to retrieve capabilities data: %s", strerror(errno));
free(hdr);
free(*data);
return false;
}

// Free allocated memory
free(hdr);

return true;
}

/**
* @brief Checks if a specific capability is available.
*
* This function retrieves the current capabilities of the process and checks if
* the specified capability is both permitted and effective.
*
* @param cap The capability to check.
* @return true if the capability is available, false otherwise.
*/
bool check_capability(const unsigned int cap)
{
cap_user_data_t data = NULL;
if(!get_caps(&data))
return false;

// Check if the capability is available
const bool available = ((data->permitted & (1 << cap)) && (data->effective & (1 << cap)));

// Free memory
free(hdr);
free(data);

return available;
}

/**
* @brief Checks the required Linux capabilities for the application.
*
* This function retrieves the current Linux capabilities and logs the status of
* each capability. It then checks if the necessary capabilities for the
* application are available and logs warnings if any required capability is
* missing.
*
* @return true if all required capabilities are available, false otherwise.
*/
bool check_capabilities(void)
{
// First assume header version 1
int capsize = 1; // VFS_CAP_U32_1
cap_user_data_t data = NULL;
cap_user_header_t hdr = calloc(sizeof(*hdr), capsize);

// Determine capabilities version used by the current kernel
capget(hdr, NULL);

// Check version
if (hdr->version != LINUX_CAPABILITY_VERSION_1)
{
// If unknown version, use largest supported version (3)
// Version 2 is deprecated according to linux/capability.h
if (hdr->version != LINUX_CAPABILITY_VERSION_2)
{
hdr->version = LINUX_CAPABILITY_VERSION_3;
capsize = 2; // VFS_CAP_U32_3
}
else
{
// Use version 2
capsize = 2; // VFS_CAP_U32_2
}
}

// Get current capabilities
data = calloc(sizeof(*data), capsize);
capget(hdr, data);
if(!get_caps(&data))
return false;

log_debug(DEBUG_CAPS, "***************************************");
log_debug(DEBUG_CAPS, "* Linux capability debugging enabled *");
Expand Down Expand Up @@ -150,7 +174,6 @@ bool check_capabilities(void)
}

// Free allocated memory
free(hdr);
free(data);

// Return whether capabilities are all okay
Expand Down
2 changes: 1 addition & 1 deletion test/arch_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ elif [[ "${CI_ARCH}" == "linux/386" ]]; then
check_machine "ELF32" "Intel 80386"
check_static # Binary should not rely on any dynamic interpreter
check_libs "" # No dependency on any shared library is intended
check_file "ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, with debug_info, not stripped"
check_file "ELF 32-bit LSB executable, Intel i386, version 1 (SYSV), statically linked, with debug_info, not stripped"

elif [[ "${CI_ARCH}" == "linux/arm/v5" ]]; then

Expand Down
Loading