pulse-server: add pulse.allow-module-loading option

Add an option to disable loading and unloading of modules with the
native protocol.

Document some more options.
This commit is contained in:
Wim Taymans 2024-05-06 15:28:43 +02:00
parent a3ccbd00b4
commit a30c27dce0
4 changed files with 52 additions and 0 deletions

View file

@ -101,6 +101,7 @@ pulse.properties = {
#}
]
#server.dbus-name = "org.pulseaudio.Server"
#pulse.allow-module-loading = true
#pulse.min.req = 128/48000 # 2.7ms
#pulse.default.req = 960/48000 # 20 milliseconds
#pulse.min.frag = 128/48000 # 2.7ms

View file

@ -63,6 +63,8 @@
* # client.access = "restricted" # permissions for clients
* #}
* ]
* #server.dbus-name = "org.pulseaudio.Server"
* #pulse.allow-module-loading = true
* #pulse.min.req = 128/48000 # 2.7ms
* #pulse.default.req = 960/48000 # 20 milliseconds
* #pulse.min.frag = 128/48000 # 2.7ms
@ -71,7 +73,9 @@
* #pulse.min.quantum = 128/48000 # 2.7ms
* #pulse.default.format = F32
* #pulse.default.position = [ FL FR ]
* #pulse.idle.timeout = 0
* }
*
* pulse.properties.rules = [
* { matches = [ { cpu.vm.name = !null } ]
* actions = {
@ -117,6 +121,20 @@
* By default network access is given the "restricted" permissions. The session manager is responsible
* for assigning permission to clients with restricted permissions (usually read-only permissions).
*
*\code{.unparsed}
* server.dbus-name = "org.pulseaudio.Server"
*\endcode
*
* The DBus name to reserve for the server. If you have multiple servers, you might want
* to change the name.
*
*\code{.unparsed}
* pulse.allow-module-loading = true
*\endcode
*
* By default, clients are allowed to load and unload modules. You can disable this
* feature with this option.
*
* ### Playback buffering options
*
*\code{.unparsed}
@ -217,6 +235,16 @@
* Normally the channels would be fixed to the sink/source that the stream connects
* to. When an invalid position (null or "") is set, the FIX_CHANNELS flag is ignored.
*
*\code{.unparsed}
* pulse.idle.timeout = 0
*\endcode
*
* Some clients are not sending data when they should and cause underruns. When
* setting this option such clients will be set to paused if they underrun
* for the given amount of seconds. This makes sure that sinks can suspend and
* save battery power. When the client resumes, it will unpause again.
* A value of 0 disables this feature.
*
* ## Command execution
*
* As part of the server startup sequence, a set of commands can be executed.
@ -286,6 +314,7 @@
* update-props = {
* pulse.min.req = 1024/48000 # 21ms
* pulse.min.quantum = 1024/48000 # 21ms
* pulse.idle.timeout = 5 # pause after 5 seconds of underrun
* }
* }
* }
@ -341,6 +370,7 @@
* update-props = {
* pulse.min.req = 1024/48000 # 21ms
* pulse.min.quantum = 1024/48000 # 21ms
* pulse.idle.timeout = 5 # pause after 5 seconds of underrun
* }
* }
* }

View file

@ -25,6 +25,7 @@ struct pw_work_queue;
struct pw_properties;
struct defs {
bool allow_module_loading;
struct spa_fraction min_req;
struct spa_fraction default_req;
struct spa_fraction min_frag;

View file

@ -56,6 +56,7 @@
#include "utils.h"
#include "volume.h"
#define DEFAULT_ALLOW_MODULE_LOADING "true"
#define DEFAULT_MIN_REQ "128/48000"
#define DEFAULT_DEFAULT_REQ "960/48000"
#define DEFAULT_MIN_FRAG "128/48000"
@ -5014,6 +5015,9 @@ static int do_load_module(struct client *client, uint32_t command, uint32_t tag,
struct pending_module *pm;
int r;
if (!impl->defs.allow_module_loading)
return -EACCES;
if (message_get(m,
TAG_STRING, &name,
TAG_STRING, &argument,
@ -5059,6 +5063,9 @@ static int do_unload_module(struct client *client, uint32_t command, uint32_t ta
struct module *module;
uint32_t module_index;
if (!impl->defs.allow_module_loading)
return -EACCES;
if (message_get(m,
TAG_U32, &module_index,
TAG_INVALID) < 0)
@ -5449,9 +5456,22 @@ static int parse_uint32(struct pw_properties *props, const char *key, const char
pw_log_info(": defaults: %s = %u", key, *res);
return 0;
}
static int parse_bool(struct pw_properties *props, const char *key, const char *def,
bool *res)
{
const char *str;
if (props == NULL ||
(str = pw_properties_get(props, key)) == NULL)
str = def;
*res = spa_atob(str);
pw_log_info(": defaults: %s = %s", key, *res ? "true" : "false");
return 0;
}
static void load_defaults(struct defs *def, struct pw_properties *props)
{
parse_bool(props, "pulse.allow-module-loading", DEFAULT_ALLOW_MODULE_LOADING,
&def->allow_module_loading);
parse_frac(props, "pulse.min.req", DEFAULT_MIN_REQ, &def->min_req);
parse_frac(props, "pulse.default.req", DEFAULT_DEFAULT_REQ, &def->default_req);
parse_frac(props, "pulse.min.frag", DEFAULT_MIN_FRAG, &def->min_frag);