grthtrhthjhtyjytjytkergtrhtrjytjerhrfh4:24 29/09/2026#!/usr/bin/bash # Refresh-only, and every path exits 0: this runs from %posttrans. policy_name="${1:-imunify360}" te_primary_dir="${SELINUX_TE_PRIMARY_DIR:-/opt/imunify360/venv/share/imunify360}" te_fallback_dir="${SELINUX_TE_FALLBACK_DIR:-/usr/share/imunify360}" hll_pp="${SELINUX_HLL_PP:-/usr/libexec/selinux/hll/pp}" note() { printf '[selinux-policy] %s\n' "$1"; } skip() { note "$1"; exit 0; } bail() { printf '[selinux-policy] %s\n' "$1" >&2; exit 0; } case "$policy_name" in "" | *[!a-z0-9_-]*) bail "refusing an unexpected policy name: $policy_name" ;; esac # 0 loaded, 1 not loaded, 2 the store could not be listed at all. policy_is_loaded() { local listing module _rest if ! listing="$(semodule -l 2>/dev/null)"; then return 2 fi while read -r module _rest; do if [ "$module" = "$policy_name" ]; then return 0 fi done <<< "$listing" return 1 } # CIL expressions may span lines; pipefail so a dead converter is not "short". rules_of() { ( set -o pipefail case "$1" in *.cil) cat -- "$1" 2>/dev/null ;; *) "$hll_pp" "$1" 2>/dev/null ;; esac | awk ' /^[[:space:]]*(;|$)/ { next } /^[[:space:]]/ { sub(/^[[:space:]]+/, " "); stmt = stmt $0; next } { if (stmt != "") print stmt; stmt = $0 } END { if (stmt != "") print stmt } ' | sort ) } extract_loaded_rules() { rm -rf "$extract_dir" && mkdir -p "$extract_dir" || return 1 ( cd "$extract_dir" && semodule -E "$policy_name" >/dev/null 2>&1 ) || return 1 # semodule -E names the file after the install language, not always .pp. local extracted for extracted in "$extract_dir/${policy_name}".*; do [ -f "$extracted" ] || continue rules_of "$extracted" > "$1" || continue [ -s "$1" ] && return 0 done return 1 } command -v semodule >/dev/null 2>&1 \ || skip "semodule not found; skipping" command -v getenforce >/dev/null 2>&1 \ || skip "getenforce not found; skipping" # A failed probe is not an answer, and the message is the only signal left. if ! enforce_state="$(getenforce 2>/dev/null)"; then bail "getenforce failed; cannot tell whether SELinux is enabled" fi case "$enforce_state" in "" | Disabled) skip "SELinux is disabled; skipping" ;; esac policy_is_loaded case "$?" in 0) ;; 2) bail "semodule -l failed; cannot tell whether $policy_name is loaded" ;; *) skip "$policy_name is not loaded; leaving the first load to the deploy script" ;; esac te_path="" for candidate in \ "${te_primary_dir}/${policy_name}.te" \ "${te_fallback_dir}/${policy_name}.te"; do if [ -f "$candidate" ]; then te_path="$candidate" break fi done [ -n "$te_path" ] || skip "${policy_name}.te not found; skipping" command -v checkmodule >/dev/null 2>&1 \ || skip "checkmodule not found; skipping" command -v semodule_package >/dev/null 2>&1 \ || skip "semodule_package not found; skipping" # Absent on the pre-CIL store, where the loaded module cannot be read back. [ -x "$hll_pp" ] \ || skip "$hll_pp not found; skipping" workdir="$(mktemp -d -t imunify-selinux-XXXXXX)" [ -d "$workdir" ] || bail "failed to create a temp directory" trap 'rm -rf "$workdir"' EXIT extract_dir="$workdir/loaded" # checkmodule and semodule both want the base name to match the module name. mod_path="$workdir/${policy_name}.mod" shipped_pp="$workdir/${policy_name}.pp" checkmodule -M -m -o "$mod_path" "$te_path" >/dev/null \ || bail "checkmodule failed for $te_path" semodule_package -o "$shipped_pp" -m "$mod_path" >/dev/null \ || bail "semodule_package failed" rules_of "$shipped_pp" > "$workdir/shipped.rules" \ || bail "could not read the rules of $te_path" [ -s "$workdir/shipped.rules" ] || bail "could not read the rules of $te_path" extract_loaded_rules "$workdir/loaded.rules" \ || bail "could not read the loaded $policy_name module" if cmp -s "$workdir/shipped.rules" "$workdir/loaded.rules"; then skip "$policy_name policy already matches the loaded module" fi note "$policy_name policy differs from the loaded module ($( comm -23 "$workdir/shipped.rules" "$workdir/loaded.rules" | wc -l ) shipped rule(s) missing, $( comm -13 "$workdir/shipped.rules" "$workdir/loaded.rules" | wc -l ) stale); reloading" semodule -i "$shipped_pp" || bail "semodule -i failed" # Confirm the reload landed instead of trusting semodule's exit status. if extract_loaded_rules "$workdir/after.rules" \ && cmp -s "$workdir/shipped.rules" "$workdir/after.rules"; then note "$policy_name SELinux policy reloaded" else bail "$policy_name was reloaded but still differs from $te_path" fi