feat: build system hardening — collision detection, validation gates, init path enforcement
5-phase hardening to prevent silent file-layer collisions (the D-Bus regression class): Phase 1: lint-config-paths.sh + make lint-config in depends.mk Phase 2: CollisionTracker in installer (content-hash comparison) Phase 3: installs manifests in recipe.toml + validate-file-ownership.sh Phase 4: validate-init-services.sh + make validate in disk.mk Phase 5: documentation (AGENTS.md, BUILD-SYSTEM-HARDENING-PLAN.md) Both redbear-mini and redbear-full build and validate clean. 66 declared install paths in base, zero conflicts.
This commit is contained in:
Executable
+81
@@ -0,0 +1,81 @@
|
||||
#!/bin/bash
|
||||
# lint-config-paths.sh — Detect init service file path violations in config files
|
||||
#
|
||||
# Init service files in config [[files]] entries MUST use /etc/init.d/ paths,
|
||||
# NOT /usr/lib/init.d/. The base package installs to /usr/lib/init.d/ and
|
||||
# silently overwrites any config files placed there during install_dir().
|
||||
#
|
||||
# The init system's config_for_dirs() gives /etc/init.d/ priority over
|
||||
# /usr/lib/init.d/ for the same filename, so config overrides must use /etc/.
|
||||
#
|
||||
# Usage:
|
||||
# scripts/lint-config-paths.sh # Check all redbear configs
|
||||
# scripts/lint-config-paths.sh config/*.toml # Check specific files
|
||||
#
|
||||
# Exit codes:
|
||||
# 0 — No violations found
|
||||
# 1 — Violations found (printed to stderr)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Default to all redbear configs if no arguments
|
||||
if [ $# -eq 0 ]; then
|
||||
set -- config/redbear-*.toml
|
||||
fi
|
||||
|
||||
violations=0
|
||||
|
||||
for config_file in "$@"; do
|
||||
if [ ! -f "$config_file" ]; then
|
||||
echo "WARN: $config_file not found, skipping" >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
# Find [[files]] entries with /usr/lib/init.d/ paths
|
||||
# We look for path = "/usr/lib/init.d/..." lines
|
||||
line_num=0
|
||||
in_files_section=false
|
||||
|
||||
while IFS= read -r line; do
|
||||
line_num=$((line_num + 1))
|
||||
|
||||
# Track TOML structure to only check [[files]] sections
|
||||
if [[ "$line" =~ ^\[\[files\]\] ]]; then
|
||||
in_files_section=true
|
||||
continue
|
||||
elif [[ "$line" =~ ^\[ ]]; then
|
||||
in_files_section=false
|
||||
continue
|
||||
fi
|
||||
|
||||
if $in_files_section; then
|
||||
# Check for /usr/lib/init.d/ paths
|
||||
if [[ "$line" =~ path[[:space:]]*=[[:space:]]*\"/usr/lib/init\.d/ ]]; then
|
||||
echo "VIOLATION: $config_file:$line_num" >&2
|
||||
echo " Line: $line" >&2
|
||||
echo " Fix: Change /usr/lib/init.d/ to /etc/init.d/" >&2
|
||||
echo "" >&2
|
||||
violations=$((violations + 1))
|
||||
fi
|
||||
|
||||
# Also check for /usr/lib/environment.d/ (similar override pattern)
|
||||
if [[ "$line" =~ path[[:space:]]*=[[:space:]]*\"/usr/lib/environment\.d/ ]]; then
|
||||
echo "VIOLATION: $config_file:$line_num" >&2
|
||||
echo " Line: $line" >&2
|
||||
echo " Fix: Change /usr/lib/environment.d/ to /etc/environment.d/" >&2
|
||||
echo "" >&2
|
||||
violations=$((violations + 1))
|
||||
fi
|
||||
fi
|
||||
done < "$config_file"
|
||||
done
|
||||
|
||||
if [ $violations -gt 0 ]; then
|
||||
echo "FAILED: $violations init service path violation(s) found." >&2
|
||||
echo "Config [[files]] entries must use /etc/init.d/ not /usr/lib/init.d/" >&2
|
||||
echo "See: local/docs/BUILD-SYSTEM-HARDENING-PLAN.md Phase 1" >&2
|
||||
exit 1
|
||||
else
|
||||
echo "OK: No init service path violations in config files."
|
||||
exit 0
|
||||
fi
|
||||
Reference in New Issue
Block a user