diff --git a/meson_options.txt b/meson_options.txt index 99b057c52..af72586b0 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -285,3 +285,36 @@ option('compress-offload', description: 'Enable ALSA Compress-Offload support', type: 'feature', value: 'disabled') +option('pam-defaults-install', + description: 'Install limits.d file modifying defaults for all PAM users. Only for old kernels/systemd!', + type: 'boolean', + value: 'false') +option('pam-memlock-default', + description : 'The default memlock value for any PAM user in kilobytes. Multiples of 64 recommended.', + type : 'integer', + min: 640, + value: 8192) +option('rlimits-install', + description: 'Install PAM limits.d file. Voids all following rlimits-* options, if false', + type: 'boolean', + value: 'true') +option('rlimits-match', + description : 'PAM match rule for the generated limits.d file. @ denotes matching a group.', + type : 'string', + value: '@pipewire') +option('rlimits-rtprio', + description : 'RR and FIFO scheduler priority permitted for realtime threads of the matching user(s)', + type : 'integer', + min: 11, + max: 99, + value: 95) +option('rlimits-memlock', + description : 'kB of memory each process of the user matched by the rule can lock. Can be unlimited .', + type : 'string', + value: '4194304') +option('rlimits-nice', + description : 'Not niceness permitted for non-realtime threads of the matching user(s)', + type : 'integer', + min: -20, + max: -1, + value: -19) diff --git a/src/modules/meson.build b/src/modules/meson.build index 633592a20..717fbf2a6 100644 --- a/src/modules/meson.build +++ b/src/modules/meson.build @@ -1,3 +1,4 @@ +subdir('module-rt') subdir('spa') # The list of "main" source files for modules, the ones that have the diff --git a/src/modules/module-rt/20-pw-defaults.conf.in b/src/modules/module-rt/20-pw-defaults.conf.in new file mode 100644 index 000000000..5f58e6c92 --- /dev/null +++ b/src/modules/module-rt/20-pw-defaults.conf.in @@ -0,0 +1,20 @@ +# This file was installed by PipeWire project for buffer locking to always work + +# Required to memlock audio buffers for all client types +# +# This will match all PAM users i.e. those going through the login procedure but +# it should not get applied to system daemons, since they are run bypassing PAM. +# +# While at first glance this might appear very relevant, in fact abusing this +# can at most allow for either more rapid OOM or enhance malicious system memory +# thrashing while evading systemd-oomd limits that are based on the requirement +# that swap utilization must be high before issues arise. As such it's perfectly +# reasonable to just set a limit where each client can lock a few megabytes with +# nearly no impact on regular systems. Meanwhile malicious attackers can OOM +# just as they could. And instead tooling for OOM and resource abuse should be +# improved, if such denial of service attacks are a serious consideration at all. +# +# Starting with Linux 5.16 or systemd v253 the default is 8192 which is plenty +# good enough and this file should not be installed on such systems. +# +* - memlock @PAM_MEMLOCK@ diff --git a/src/modules/module-rt/25-pw-rlimits.conf.in b/src/modules/module-rt/25-pw-rlimits.conf.in new file mode 100644 index 000000000..4714d7e5a --- /dev/null +++ b/src/modules/module-rt/25-pw-rlimits.conf.in @@ -0,0 +1,8 @@ +# This file was installed by PipeWire project for its libpipewire-module-rt.so + +# It's believed to be acceptable to have match rules that will never be true +# i.e. a group that does not exist. +# +@MATCH@ - rtprio @RTPRIO@ +@MATCH@ - nice @NICE@ +@MATCH@ - memlock @MEMLOCK@ diff --git a/src/modules/module-rt/meson.build b/src/modules/module-rt/meson.build new file mode 100644 index 000000000..a41fe059d --- /dev/null +++ b/src/modules/module-rt/meson.build @@ -0,0 +1,23 @@ +rlimits_install = get_option('rlimits-install') +rlimits_data = configuration_data() +rlimits_data.set('MATCH', get_option('rlimits-match')) +rlimits_data.set('RTPRIO', get_option('rlimits-rtprio')) +rlimits_data.set('NICE', get_option('rlimits-nice')) +rlimits_data.set('MEMLOCK', get_option('rlimits-memlock')) +configure_file(input: '25-pw-rlimits.conf.in', + output: '25-pw-rlimits.conf', + install: rlimits_install, + install_dir: get_option('sysconfdir') / 'security' / 'limits.d', + configuration: rlimits_data) +summary({'RLIMITs': '@0@ limits.d file affecting matching PAM users'.format(rlimits_install ? 'with' : 'without')}) + +# The pam-defaults-install related code can be removed once all Linux <5.16 kernels are EOL (projected Dec, 2026) +pam_defaults_install = get_option('pam-defaults-install') +pam_defaults_data = configuration_data() +pam_defaults_data.set('PAM_MEMLOCK', get_option('pam-memlock-default')) +configure_file(input: '20-pw-defaults.conf.in', + output: '20-pw-defaults.conf', + install: pam_defaults_install, + install_dir: get_option('sysconfdir') / 'security' / 'limits.d', + configuration: pam_defaults_data) +summary({'PAM defaults': '@0@ limits.d file affecting all PAM users (not needed with modern systemd or kernel)'.format(pam_defaults_install ? 'with' : 'without')})