Skip to content

Commit

Permalink
init: optionally load the system SELinux policy
Browse files Browse the repository at this point in the history
  • Loading branch information
WavyEbuilder committed Oct 18, 2024
1 parent e7ad5b1 commit 69d80f4
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 2 deletions.
1 change: 1 addition & 0 deletions CONTRIBUTORS
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ The following people (in alphabetical order) have contributed:
* Oliver Amann - Code, testing, documentation
* Locria Cyber - Code, documentation
* q66 - Code, testing, documentation.
* Rahul Sandhu - Code
3 changes: 2 additions & 1 deletion build/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ includes/mconfig.h: ../mconfig tools/mconfig-gen.cc version.conf
DEFAULT_STOP_TIMEOUT=$(DEFAULT_STOP_TIMEOUT) \
$(if $(SUPPORT_CGROUPS),SUPPORT_CGROUPS=$(SUPPORT_CGROUPS),) \
$(if $(USE_UTMPX),USE_UTMPX=$(USE_UTMPX),) \
$(if $(USE_INITGROUPS),USE_INITGROUPS=$(USE_INITGROUPS),) > includes/mconfig.h
$(if $(USE_INITGROUPS),USE_INITGROUPS=$(USE_INITGROUPS),) \
$(if $(SUPPORT_SELINUX),SUPPORT_SELINUX=$(SUPPORT_SELINUX),) > includes/mconfig.h

clean:
rm -f includes/mconfig.h
Expand Down
1 change: 1 addition & 0 deletions build/mconfig.mesontemplate
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#mesondefine USE_UTMPX
#mesondefine USE_INITGROUPS
#mesondefine SUPPORT_CGROUPS
#mesondefine SUPPORT_SELINUX
#mesondefine DEFAULT_AUTO_RESTART
#mesondefine DEFAULT_START_TIMEOUT
#mesondefine DEFAULT_STOP_TIMEOUT
Expand Down
3 changes: 3 additions & 0 deletions build/tools/mconfig-gen.cc
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ int main(int argc, char **argv)
if (vars.find("DEFAULT_AUTO_RESTART") != vars.end()) {
cout << "#define DEFAULT_AUTO_RESTART " << vars["DEFAULT_AUTO_RESTART"] << "\n";
}
if (vars.find("SUPPORT_SELINUX") != vars.end()) {
cout << "#define SUPPORT_SELINUX " << vars["SUPPORT_SELINUX"] << "\n";
}

cout << "\n// Constants\n";
cout << "\nconstexpr static char DINIT_VERSION[] = " << stringify(vars["VERSION"]) << ";\n";
Expand Down
9 changes: 9 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ Optional options:
--disable-utmpx Disable manipulating the utmp/utmpx database via the related POSIX functions
--enable-initgroups Enable initialization of supplementary groups for run-as [Enabled]
--disable-initgroups Disable initialization of supplementary groups for run-as
--enable-selinux Enable SELinux support [Enabled only on Linux based systems]
--enable-auto-restart Enable auto-restart for services by default [Deprecated]
--disable-auto-restart Disable auto-restart for services by default [Deprecated]
--default-start-timeout=sec Default start-timeout for services [60]
Expand Down Expand Up @@ -210,6 +211,7 @@ for var in PREFIX \
SUPPORT_CGROUPS \
USE_UTMPX \
USE_INITGROUPS \
SUPPORT_SELINUX \
SYSCONTROLSOCKET \
STRIPOPTS
do
Expand Down Expand Up @@ -243,6 +245,8 @@ for arg in "$@"; do
--disable-utmpx|--enable-utmpx=no) USE_UTMPX=0 ;;
--enable-initgroups|--enable-initgroups=yes) USE_INITGROUPS=1 ;;
--disable-initgroups|--enable-initgroups=no) USE_INITGROUPS=0 ;;
--enable-selinux|--enable-selinux=yes) SUPPORT_SELINUX=1 ;;
--disable-selinux|--enable-selinux=no) SUPPORT_SELINUX=0 ;;
--enable-auto-restart|--enable-auto-restart=yes) DEFAULT_AUTO_RESTART=ALWAYS ;; # Deprecated
--disable-auto-restart|--enable-auto-restart=no) DEFAULT_AUTO_RESTART=NEVER ;; # Deprecated
--enable-strip|--enable-strip=yes) STRIPOPTS="-s" ;;
Expand Down Expand Up @@ -275,6 +279,7 @@ done
: "${DEFAULT_START_TIMEOUT:="60"}"
: "${DEFAULT_STOP_TIMEOUT:="10"}"
: "${USE_INITGROUPS:="1"}"
: "${SUPPORT_SELINUX:="0"}"
if [ "$PLATFORM" = "Linux" ]; then
: "${BUILD_SHUTDOWN:="yes"}"
: "${SUPPORT_CGROUPS:="1"}"
Expand Down Expand Up @@ -380,6 +385,9 @@ fi
if [ "$AUTO_LDFLAGS_BASE" = true ] && [ "$PLATFORM" = FreeBSD ]; then
try_ld_argument LDFLAGS_BASE -lrt
fi
if [ "$AUTO_LDFLAGS_BASE" = true ] && [ "$SUPPORT_SELINUX" = "1" ]; then
try_ld_argument LDFLAGS_BASE -lselinux
fi
if [ "$AUTO_TEST_LDFLAGS_BASE" = true ]; then
TEST_LDFLAGS_BASE="\$(LDFLAGS_BASE)"
established_TEST_LDFLAGS="$LDFLAGS_BASE"
Expand Down Expand Up @@ -467,6 +475,7 @@ STRIPOPTS=$STRIPOPTS
# Feature settings
SUPPORT_CGROUPS=$SUPPORT_CGROUPS
USE_INITGROUPS=$USE_INITGROUPS
SUPPORT_SELINUX=$SUPPORT_SELINUX
# Optional settings
SHUTDOWN_PREFIX=${SHUTDOWN_PREFIX:-}
Expand Down
2 changes: 2 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ man_pages = get_option('man-pages')
support_cgroups = get_option('support-cgroups')
use_utmpx = get_option('use-utmpx')
use_initgroups = get_option('use-initgroups')
libselinux = dependency('libselinux', version : '>= 2.1.9', required : get_option('selinux'))
default_auto_restart = get_option('default-auto-restart')
default_start_timeout = get_option('default-start-timeout').to_string()
default_stop_timeout = get_option('default-stop-timeout').to_string()
Expand Down Expand Up @@ -65,6 +66,7 @@ mconfig_data.set('DEFAULT_AUTO_RESTART', default_auto_restart)
mconfig_data.set('DEFAULT_START_TIMEOUT', default_start_timeout)
mconfig_data.set('DEFAULT_STOP_TIMEOUT', default_stop_timeout)
mconfig_data.set10('USE_INITGROUPS', use_initgroups)
mconfig_data.set10('SUPPORT_SELINUX', libselinux.found())
if support_cgroups.auto() and platform == 'linux' or support_cgroups.enabled()
mconfig_data.set('SUPPORT_CGROUPS', '1')
endif
Expand Down
6 changes: 6 additions & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,9 @@ option(
value : 'auto',
description : 'Building shutdown/reboot/soft-reboot/halt or not.'
)
option(
'selinux',
type : 'feature',
value : 'auto',
description : 'SELinux support'
)
72 changes: 72 additions & 0 deletions src/dinit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@

#include "mconfig.h"

#if SUPPORT_SELINUX
#include <selinux/avc.h>
#include <selinux/label.h>
#include <selinux/selinux.h>
#endif

/*
* When running as the system init process, Dinit processes the following signals:
*
Expand Down Expand Up @@ -453,6 +459,70 @@ static int process_commandline_arg(char **argv, int argc, int &i, options &opts)
return 0;
}

bool selinux_transition(const char *exe) {
#if SUPPORT_SELINUX
using std::cerr;
using std::endl;

char *current_context = nullptr;
char *file_context = nullptr;
security_class_t security_class;
char *new_context = nullptr;

if (is_selinux_enabled() == 1) {
return true;
}

int enforce = 0;
if (selinux_init_load_policy(&enforce) != 0) {
if (enforce > 0) {
cerr << "Failed to load SELinux policy." << endl;
return false;
}
}

bool ret = true;
if (getcon_raw(&current_context) < 0) {
ret = false;
cerr << "Failed to get current context: " << strerror(errno) << endl;
goto cleanup;
}

if (getfilecon_raw(exe, &file_context) < 0) {
ret = false;
cerr << "Failed to get file context for " << exe << ": " << strerror(errno) << endl;
goto cleanup;
}

security_class = string_to_security_class("process");
if (security_class == 0) {
ret = false;
cerr << "Failed to get security class for process" << endl;
goto cleanup;
}

if (security_compute_create_raw(current_context, file_context, security_class, &new_context) < 0) {
ret = false;
cerr << "Failed to compute create context: " << strerror(errno) << endl;
goto cleanup;
}

if (setcon_raw(new_context) < 0) {
ret = false;
cerr << "Failed to set transition context to " << new_context << ": " << strerror(errno) << endl;
goto cleanup;
}

cleanup:
if (current_context) freecon(current_context);
if (file_context) freecon(file_context);
if (new_context) freecon(new_context);
return ret;
#else
return true;
#endif
}

// Main entry point
int dinit_main(int argc, char **argv)
{
Expand All @@ -461,6 +531,8 @@ int dinit_main(int argc, char **argv)
am_system_mgr = (getpid() == 1);
am_system_init = (getuid() == 0);

if (am_system_mgr && am_system_init && !selinux_transition(argv[0])) return 1;

struct options opts;

// if we are PID 1 and user id 0, we are *most probably* the system init. (Or on linux at least, we
Expand Down
9 changes: 8 additions & 1 deletion src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ dinit_source_files = [
'dinit-env.cc',
'settings.cc'
]
dinit_dependencies = []

if libselinux.found()
dinit_dependencies += libselinux
endif


## src/'s Defines
shutdown_built = false
Expand All @@ -40,7 +46,8 @@ endif
executable(
'dinit',
dinit_source_files,
kwargs: misc_args
kwargs: misc_args,
dependencies: dinit_dependencies
)
executable(
'dinitctl',
Expand Down

0 comments on commit 69d80f4

Please sign in to comment.