veilor-os/scripts/selinux/veilor-firstboot.te

137 lines
5.8 KiB
Text
Raw Normal View History

policy_module(veilor-firstboot, 1.0)
#
# veilor-os SELinux module — confine veilor-firstboot.service.
#
# The firstboot service runs once on TTY1 before SDDM, prompts for the
# admin password, then enables SDDM and self-disables. It is privileged
# (it must be — `passwd` writes /etc/shadow) but the surface is small and
# bounded. This module narrows what the service is allowed to do so that a
# bug or hostile env in firstboot.sh can't, e.g., dial out, scrape /home,
# or load a kernel module.
#
# Build + load:
# cd scripts/selinux
# ./build-policy.sh # builds & loads all .te modules
#
# Verify:
# semodule -l | grep veilor-firstboot
# ls -Z /usr/local/sbin/veilor-firstboot
# -> system_u:object_r:veilor_firstboot_exec_t:s0
#
# Audit any denials with:
# ausearch -m AVC -ts recent -c veilor-firstboot
require {
type init_t;
type passwd_exec_t;
type passwd_file_t;
type shadow_t;
type systemd_unit_file_t;
type systemd_passwd_var_run_t;
type sddm_unit_file_t;
type sddm_var_lib_t;
type tmp_t;
type tty_device_t;
type devtty_t;
type self_runtime_t;
type chkpwd_exec_t;
type pam_var_run_t;
type security_t;
type fs_t;
type usr_t;
type bin_t;
type lib_t;
type etc_t;
type proc_t;
type unconfined_service_t;
class file { read write create unlink getattr setattr open execute execute_no_trans map };
class dir { read write add_name remove_name search getattr open };
class chr_file { read write open getattr ioctl };
class capability { setuid setgid chown dac_override dac_read_search fowner fsetid };
class process { transition signal sigchld sigkill noatsecure rlimitinh siginh };
class service { start stop status enable disable };
class systemd { start };
class lnk_file { read getattr };
class filesystem { getattr };
}
# ---------------------------------------------------------------------
# 1. Define the firstboot domain + executable type
# ---------------------------------------------------------------------
type veilor_firstboot_t;
type veilor_firstboot_exec_t;
type veilor_firstboot_state_t; # /var/lib/veilor-firstboot.done
init_daemon_domain(veilor_firstboot_t, veilor_firstboot_exec_t)
files_type(veilor_firstboot_state_t)
# Auto-transition: when init_t executes /usr/local/sbin/veilor-firstboot,
# enter veilor_firstboot_t.
domain_auto_trans(init_t, veilor_firstboot_exec_t, veilor_firstboot_t)
# ---------------------------------------------------------------------
# 2. Allow rules — what the service IS allowed to do
# ---------------------------------------------------------------------
# read /etc/passwd, /etc/group, /etc/shadow (passwd needs shadow write)
allow veilor_firstboot_t passwd_file_t:file { read getattr open };
allow veilor_firstboot_t shadow_t:file { read write open getattr setattr };
# exec passwd(1)
allow veilor_firstboot_t passwd_exec_t:file { read getattr open execute execute_no_trans map };
allow veilor_firstboot_t chkpwd_exec_t:file { read getattr open execute execute_no_trans map };
# capabilities passwd needs
allow veilor_firstboot_t self:capability { setuid setgid chown dac_override dac_read_search fowner fsetid };
# write the state marker /var/lib/veilor-firstboot.done
allow veilor_firstboot_t veilor_firstboot_state_t:file { create write open getattr setattr unlink };
allow veilor_firstboot_t veilor_firstboot_state_t:dir { search write add_name remove_name };
# write /etc/sddm.conf.d/ entries (autologin disable, theme, etc.)
allow veilor_firstboot_t sddm_var_lib_t:dir { read write search add_name remove_name open };
allow veilor_firstboot_t sddm_var_lib_t:file { read write create open getattr setattr };
# start sddm.service via systemctl
allow veilor_firstboot_t sddm_unit_file_t:file { read getattr open };
allow veilor_firstboot_t sddm_unit_file_t:service { start status enable disable };
allow veilor_firstboot_t init_t:system { start };
# tty1 I/O
allow veilor_firstboot_t tty_device_t:chr_file { read write open getattr ioctl };
allow veilor_firstboot_t devtty_t:chr_file { read write open getattr ioctl };
# usual base reads
allow veilor_firstboot_t bin_t:file { read getattr open execute execute_no_trans map };
allow veilor_firstboot_t lib_t:file { read getattr open execute execute_no_trans map };
allow veilor_firstboot_t usr_t:file { read getattr open };
allow veilor_firstboot_t etc_t:file { read getattr open };
allow veilor_firstboot_t etc_t:dir { read search getattr open };
allow veilor_firstboot_t fs_t:filesystem getattr;
allow veilor_firstboot_t self:fifo_file { read write };
allow veilor_firstboot_t self:unix_stream_socket { create connect read write };
# ---------------------------------------------------------------------
# 3. Deny rules — what the service is NOT allowed to do
# ---------------------------------------------------------------------
# no network — firstboot must never phone home
neverallow veilor_firstboot_t self:tcp_socket *;
neverallow veilor_firstboot_t self:udp_socket *;
neverallow veilor_firstboot_t self:rawip_socket *;
neverallow veilor_firstboot_t self:packet_socket *;
neverallow veilor_firstboot_t self:netlink_route_socket *;
# no kernel module load
neverallow veilor_firstboot_t self:capability sys_module;
# no /home access except the bits ferror-firstboot.sh writes (admin's
# .config dir staging, if any). /home/admin general read = forbidden.
neverallow veilor_firstboot_t home_root_t:dir { read write };
neverallow veilor_firstboot_t user_home_t:dir { read write search };
neverallow veilor_firstboot_t user_home_t:file { read write open };
# no ptrace, no /dev/mem, no /dev/kmem
neverallow veilor_firstboot_t self:capability sys_ptrace;
neverallow veilor_firstboot_t self:capability sys_rawio;