Skip to content

Commit

Permalink
feat: optional SELinux policy for insights-core
Browse files Browse the repository at this point in the history
insights-core will get soon an own SELinux policy, and thus
insights-client must properly run insights-core using its own policy.

To do that:
- add a new meson option to specify the type of the SELinux policy for
  insights-core; an empty string disables the switch, i.e. keep the
  current behaviour (insights-core running in the same context of
  insights-client)
- use the libselinux Python binding in case a SELinux policy for
  insights-core is specified
- detect whether SELinux is enabled, and disable the switch if not
- in case a switch has to happen, then use the existing SELinux context,
  and apply the different type for insights-core

Card: CCT-984

Signed-off-by: Pino Toscano <[email protected]>
  • Loading branch information
ptoscano committed Jan 31, 2025
1 parent a32978a commit 22efa33
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 1 deletion.
8 changes: 7 additions & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ config_data = configuration_data({
'SBINDIR': get_option('prefix') / get_option('sbindir'),
'SYSCONFDIR': '/' / get_option('sysconfdir'),
'sysconfdir': '/' / get_option('sysconfdir'),
'top_srcdir': meson.source_root()
'top_srcdir': meson.source_root(),
'CORE_SELINUX_POLICY': get_option('core_selinux_policy'),
})

run_target('update-egg', command: 'scripts/01-upgrade-egg.sh')
Expand All @@ -49,4 +50,9 @@ if get_option('auto_registration').enabled()
else
configuration += '\tauto_registration\t: ' + 'disabled' + '\n'
endif
if get_option('core_selinux_policy') != ''
configuration += '\tSELinux policy for insights-core\t: ' + get_option('core_selinux_policy') + '\n'
else
configuration += '\tSELinux policy for insights-core\t: ' + 'disabled' + '\n'
endif
message(configuration)
1 change: 1 addition & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ option('python', type: 'string', value: 'python3', description: 'python interpre
option('auto_registration', type: 'feature', value: 'disabled', description: 'enable automatic registration')
option('checkin', type: 'feature', value: 'disabled', description: 'enable hourly check-in')
option('redhat_access_insights', type: 'boolean', value: false, description: 'enable deprecated redhat-access-insights executable')
option('core_selinux_policy', type: 'string', value: '', description: 'SELinux policy for insights-core (empty: none used)')
30 changes: 30 additions & 0 deletions src/insights_client/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,25 @@

try:
from .constants import InsightsConstants
from .constants import CORE_SELINUX_POLICY

# if there is a policy for insights-core, unconditionally try to interface
# with SELinux: insights-client was built with a policy for insights-core,
# so not being able to apply that is an hard failure
if CORE_SELINUX_POLICY != "":
import selinux

SWITCH_CORE_SELINUX_POLICY = selinux.is_selinux_enabled()
else:
SWITCH_CORE_SELINUX_POLICY = False
except ImportError:
# The source file is build from 'constants.py.in' and is not
# available during development
class InsightsConstants(object):
version = "development"

CORE_SELINUX_POLICY = ""
SWITCH_CORE_SELINUX_POLICY = False

LOG_FORMAT = "%(asctime)s %(levelname)8s %(name)s:%(lineno)s %(message)s"
NO_COLOR = os.environ.get("NO_COLOR") is not None
Expand Down Expand Up @@ -306,8 +319,25 @@ def run_phase(phase, client, validated_eggs):
env = os.environ
env.update(insights_env)

if SWITCH_CORE_SELINUX_POLICY:
# in case we can switch to a different SELinux policy for
# insights-core, get the current context and switch the type
context = selinux.context_new(selinux.getcon()[1])
# additional check: in case the current type is a certain one
# (e.g. unconfined_t when insights-client is run from a shell),
# then the switch will not work
if selinux.context_type_get(context) not in ["unconfined_t", "sysadm_t"]:
selinux.context_type_set(context, CORE_SELINUX_POLICY)
new_core_context = selinux.context_str(context)
selinux.setexeccon(new_core_context)
selinux.context_free(context)
process = subprocess.Popen(insights_command, env=env)
process.communicate()
if SWITCH_CORE_SELINUX_POLICY:
# setexeccon() in theory ought to reset the context for the next
# execv*() after that execution; it does not seem to happen though,
# so for now manually reset it
selinux.setexeccon(None)
if process.returncode == 0:
# phase successful, don't try another egg
logger.debug("phase '%s' successful", phase["name"])
Expand Down
1 change: 1 addition & 0 deletions src/insights_client/constants.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ DATADIR = "@DATADIR@"
SYSCONFDIR = "@SYSCONFDIR@"
LOCALSTATEDIR = "@LOCALSTATEDIR@"
DOCDIR = "@DOCDIR@"
CORE_SELINUX_POLICY = "@CORE_SELINUX_POLICY@"


class InsightsConstants(object):
Expand Down

0 comments on commit 22efa33

Please sign in to comment.