diff --git a/policy/modules/apps/wireplumber.fc b/policy/modules/apps/wireplumber.fc new file mode 100644 index 0000000000..1a0d9a7100 --- /dev/null +++ b/policy/modules/apps/wireplumber.fc @@ -0,0 +1,15 @@ +# WirePlumber session manager executable. +/usr/bin/wireplumber -- gen_context(system_u:object_r:wireplumber_exec_t,s0) + +# System-service runtime directory (/run/wireplumber). +/run/wireplumber(/.*)? gen_context(system_u:object_r:wireplumber_runtime_t,s0) + +# User-session runtime sockets live under $XDG_RUNTIME_DIR/wireplumber and are +# labelled at runtime via userdom_user_runtime_filetrans; no static entry needed. + +# Persistent system-service state. +/var/lib/wireplumber(/.*)? gen_context(system_u:object_r:wireplumber_var_lib_t,s0) + +# User home configuration and state. +HOME_DIR/\.config/wireplumber(/.*)? gen_context(system_u:object_r:wireplumber_home_t,s0) +HOME_DIR/\.local/share/wireplumber(/.*)? gen_context(system_u:object_r:wireplumber_home_t,s0) diff --git a/policy/modules/apps/wireplumber.if b/policy/modules/apps/wireplumber.if new file mode 100644 index 0000000000..21d2805c2d --- /dev/null +++ b/policy/modules/apps/wireplumber.if @@ -0,0 +1,149 @@ +## Policy for WirePlumber, the PipeWire session manager. + +######################################## +## +## Role access for WirePlumber (user-service mode). +## Call this from unprivuser.te / staff.te in the same +## way pipewire_role is called. +## +## +## +## The prefix of the user role (e.g., "user" for user_r). +## +## +## +## +## User domain for the role (e.g., user_t). +## +## +## +## +## User exec domain for execute and transition access +## (e.g., user_application_exec_domain). +## +## +## +## +## Role allowed access (e.g., user_r). +## +## +# +template(`wireplumber_role',` + gen_require(` + attribute_role wireplumber_roles; + type wireplumber_t, wireplumber_exec_t; + type wireplumber_home_t, wireplumber_tmpfs_t, wireplumber_runtime_t; + ') + + roleattribute $4 wireplumber_roles; + + domtrans_pattern($2, wireplumber_exec_t, wireplumber_t) + domtrans_pattern($3, wireplumber_exec_t, wireplumber_t) + + allow $3 wireplumber_t:process { ptrace signal_perms }; + allow $3 wireplumber_t:fd use; + ps_process_pattern($3, wireplumber_t) + + allow wireplumber_t $3:unix_stream_socket connectto; + allow wireplumber_t $3:process signull; + + # Allow the user domain to manage and relabel wireplumber home state files + # (e.g. restorecon after reinstall, stale file cleanup). + allow $2 wireplumber_home_t:dir { manage_dir_perms relabel_dir_perms }; + allow $2 wireplumber_home_t:file { mmap_manage_file_perms relabel_file_perms }; + allow $2 wireplumber_home_t:lnk_file { manage_lnk_file_perms relabel_lnk_file_perms }; + + # Allow the user domain to manage and relabel runtime sock files + # (e.g. stale socket cleanup after daemon crash). + allow $2 wireplumber_runtime_t:dir { manage_dir_perms relabel_dir_perms }; + allow $2 wireplumber_runtime_t:sock_file { manage_sock_file_perms relabel_sock_file_perms }; + + # Allow the user domain to manage shared memory files created by the daemon. + wireplumber_mmap_rw_tmpfs_files($2) + allow $2 wireplumber_tmpfs_t:file relabel_file_perms; + + optional_policy(` + systemd_user_app_status($1, wireplumber_t) + systemd_user_app_socket_create($1, wireplumber_t, wireplumber_runtime_t) + systemd_user_daemon_domain($1, wireplumber_exec_t, wireplumber_t) + ') +') + +######################################## +## +## Execute a domain transition to run WirePlumber. +## +## +## +## Domain allowed to transition. +## +## +# +interface(`wireplumber_domtrans',` + gen_require(` + type wireplumber_t, wireplumber_exec_t; + ') + + corecmd_search_bin($1) + domtrans_pattern($1, wireplumber_exec_t, wireplumber_t) +') + +######################################## +## +## Connect to WirePlumber over a unix stream socket. +## +## +## +## Domain allowed access. +## +## +# +interface(`wireplumber_stream_connect',` + gen_require(` + type wireplumber_t, wireplumber_runtime_t; + ') + + files_search_runtime($1) + stream_connect_pattern($1, wireplumber_runtime_t, wireplumber_runtime_t, wireplumber_t) +') + +######################################## +## +## Allow a domain to read, write, and map WirePlumber shared memory (tmpfs) files. +## These are memfd files passed between WirePlumber and PipeWire for +## zero-copy audio buffer sharing. +## +## +## +## Domain allowed access. +## +## +# +interface(`wireplumber_mmap_rw_tmpfs_files',` + gen_require(` + type wireplumber_tmpfs_t; + ') + + fs_search_tmpfs($1) + mmap_rw_files_pattern($1, wireplumber_tmpfs_t, wireplumber_tmpfs_t) +') + +######################################## +## +## Allow a domain to read WirePlumber home directory content. +## +## +## +## Domain allowed access. +## +## +# +interface(`wireplumber_read_home_files',` + gen_require(` + type wireplumber_home_t; + ') + + userdom_search_user_home_dirs($1) + read_files_pattern($1, wireplumber_home_t, wireplumber_home_t) + read_lnk_files_pattern($1, wireplumber_home_t, wireplumber_home_t) +') diff --git a/policy/modules/apps/wireplumber.te b/policy/modules/apps/wireplumber.te new file mode 100644 index 0000000000..6d86fe88b0 --- /dev/null +++ b/policy/modules/apps/wireplumber.te @@ -0,0 +1,181 @@ +policy_module(wireplumber) + +######################################## +# +# Declarations +# + +## +##

+## Run WirePlumber as a system-wide daemon launched by the systemd system +## instance. When false (default), WirePlumber runs as a per-user session +## service launched by systemd --user. +## Define wireplumber_system_service at build time to enable system-service mode. +##

+##
+ +attribute_role wireplumber_roles; + +# +# wireplumber_t — the WirePlumber session manager daemon. +# +type wireplumber_t; +type wireplumber_exec_t; +ifdef(`wireplumber_system_service',` + init_daemon_domain(wireplumber_t, wireplumber_exec_t) +',` + userdom_user_application_domain(wireplumber_t, wireplumber_exec_t) + role wireplumber_roles types wireplumber_t; +') + +type wireplumber_home_t; +userdom_user_home_content(wireplumber_home_t) + +type wireplumber_var_lib_t; +files_type(wireplumber_var_lib_t) + +type wireplumber_runtime_t; +files_runtime_file(wireplumber_runtime_t) + +type wireplumber_tmpfs_t; +userdom_user_tmpfs_file(wireplumber_tmpfs_t) + +######################################## +# +# wireplumber_t — common policy (both system and user instances) +# + +allow wireplumber_t self:capability sys_nice; +allow wireplumber_t self:process { getsched setsched signal signull }; +allow wireplumber_t self:fifo_file rw_fifo_file_perms; +allow wireplumber_t self:unix_stream_socket { create_stream_socket_perms connectto }; +allow wireplumber_t self:unix_dgram_socket create_socket_perms; + +# Bluetooth socket for BlueZ audio routing (A2DP/HFP profile management). +allow wireplumber_t self:bluetooth_socket create_socket_perms; + +# netlink kobject uevent socket for udev device monitoring. +allow wireplumber_t self:netlink_kobject_uevent_socket create_socket_perms; + +# Shared memory (memfd) files for zero-copy audio buffer sharing with PipeWire. +mmap_manage_files_pattern(wireplumber_t, wireplumber_tmpfs_t, wireplumber_tmpfs_t) +fs_tmpfs_filetrans(wireplumber_t, wireplumber_tmpfs_t, file) + +# NSS/name-service lookups to resolve user names for session ownership checks. +auth_use_nsswitch(wireplumber_t) + +# Filesystem getattr for device/mount enumeration. +dev_getattr_fs(wireplumber_t) + +# Suppress noisy denials when WirePlumber probes video devices it does not use. +dev_dontaudit_getattr_video_dev(wireplumber_t) + +# Device enumeration via sysfs. +dev_read_sysfs(wireplumber_t) + +# /dev/snd inotify watch for ALSA device add/remove events. +dev_watch_dev_dirs(wireplumber_t) + +# Suppress harmless /proc//status probes during client enumeration. +domain_dontaudit_read_all_domains_state(wireplumber_t) + +files_map_usr_files(wireplumber_t) +files_read_etc_files(wireplumber_t) + +# /etc/machine-id (used for unique instance identification). +files_read_etc_runtime_files(wireplumber_t) + +files_read_usr_files(wireplumber_t) + +fs_getattr_xattr_fs(wireplumber_t) + +# Read /proc state for scheduling and memory info. +kernel_read_system_state(wireplumber_t) + +logging_send_syslog_msg(wireplumber_t) + +miscfiles_read_localization(wireplumber_t) + +# udev runtime data (/run/udev) for device property lookups. +udev_read_runtime_files(wireplumber_t) +udev_search_runtime(wireplumber_t) + +# D-Bus communication with BlueZ (Bluetooth audio routing). +optional_policy(` + bluetooth_dbus_chat(wireplumber_t) +') + +# D-Bus communication with ModemManager (telephony audio routing). +optional_policy(` + modemmanager_dbus_chat(wireplumber_t) +') + +# D-Bus communication with oFono (telephony audio routing). +optional_policy(` + ofono_dbus_chat(wireplumber_t) +') + +# Connect to the PipeWire daemon socket and map its shared memory buffers. +optional_policy(` + pipewire_mmap_rw_tmpfs_files(wireplumber_t) + pipewire_stream_connect(wireplumber_t) + pipewire_use_fds(wireplumber_t) +') + +# Real-time scheduling priority via rtkit-daemon. +optional_policy(` + rtkit_scheduled(wireplumber_t) +') + +# systemd-logind session tracking and journal logging. +optional_policy(` + systemd_read_journal_files(wireplumber_t) + systemd_read_logind_sessions_files(wireplumber_t) + systemd_watch_logind_sessions_dirs(wireplumber_t) +') + +######################################## +# +# wireplumber_t — system-service-only policy +# + +ifdef(`wireplumber_system_service',` + # Persistent state directory under /var/lib/wireplumber. + manage_dirs_pattern(wireplumber_t, wireplumber_var_lib_t, wireplumber_var_lib_t) + manage_files_pattern(wireplumber_t, wireplumber_var_lib_t, wireplumber_var_lib_t) + files_var_lib_filetrans(wireplumber_t, wireplumber_var_lib_t, { dir file }) + + # Runtime socket/pid directory transition under /run/wireplumber. + files_runtime_filetrans(wireplumber_t, wireplumber_runtime_t, dir, "wireplumber") + + manage_dirs_pattern(wireplumber_t, wireplumber_runtime_t, wireplumber_runtime_t) + manage_files_pattern(wireplumber_t, wireplumber_runtime_t, wireplumber_runtime_t) + manage_sock_files_pattern(wireplumber_t, wireplumber_runtime_t, wireplumber_runtime_t) + + # System D-Bus registration. + optional_policy(` + dbus_system_domain(wireplumber_t, wireplumber_exec_t) + ') +') + +######################################## +# +# wireplumber_t — user-service-only policy +# + +ifndef(`wireplumber_system_service',` + # Home directory state (~/.config/wireplumber, ~/.local/share/wireplumber). + # mmap_manage_file_perms includes map permission needed for config file mmap. + manage_dirs_pattern(wireplumber_t, wireplumber_home_t, wireplumber_home_t) + allow wireplumber_t wireplumber_home_t:file mmap_manage_file_perms; + manage_lnk_files_pattern(wireplumber_t, wireplumber_home_t, wireplumber_home_t) + + # Runtime socket directory transition under $XDG_RUNTIME_DIR/wireplumber. + userdom_user_runtime_filetrans(wireplumber_t, wireplumber_runtime_t, dir, "wireplumber") + + # Session D-Bus (register on the per-user session bus). + optional_policy(` + dbus_all_session_bus_client(wireplumber_t) + dbus_connect_all_session_bus(wireplumber_t) + ') +') diff --git a/policy/modules/roles/staff.te b/policy/modules/roles/staff.te index dfd4bfca8a..abf983d13e 100644 --- a/policy/modules/roles/staff.te +++ b/policy/modules/roles/staff.te @@ -170,6 +170,10 @@ ifndef(`distro_redhat',` pipewire_role(staff, staff_t, staff_application_exec_domain, staff_r) ') + optional_policy(` + wireplumber_role(staff, staff_t, staff_application_exec_domain, staff_r) + ') + optional_policy(` pyzor_role(staff, staff_t, staff_application_exec_domain, staff_r) ') diff --git a/policy/modules/roles/unprivuser.te b/policy/modules/roles/unprivuser.te index 888950f7c7..ac6dd46f2d 100644 --- a/policy/modules/roles/unprivuser.te +++ b/policy/modules/roles/unprivuser.te @@ -138,6 +138,10 @@ ifndef(`distro_redhat',` pipewire_role(user, user_t, user_application_exec_domain, user_r) ') + optional_policy(` + wireplumber_role(user, user_t, user_application_exec_domain, user_r) + ') + optional_policy(` pyzor_role(user, user_t, user_application_exec_domain, user_r) ') diff --git a/policy/modules/services/ofono.if b/policy/modules/services/ofono.if index 51c9d4e195..01528646ef 100644 --- a/policy/modules/services/ofono.if +++ b/policy/modules/services/ofono.if @@ -1,5 +1,5 @@ ## ofono -# +## ## ## oFono is a stack for mobile telephony devices on Linux. ## oFono supports speaking to telephony devices through specific drivers, @@ -7,3 +7,23 @@ ## ## https://git.kernel.org/pub/scm/network/ofono/ofono.git ## + +######################################## +## +## Allow D-Bus communication with oFono. +## +## +## +## Domain allowed access. +## +## +# +interface(`ofono_dbus_chat',` + gen_require(` + type ofono_t; + class dbus send_msg; + ') + + allow $1 ofono_t:dbus send_msg; + allow ofono_t $1:dbus send_msg; +')