282
283
#ifdef HAVE_SYS_RESOURCE_H
284
static void set_one_rlimit(const pa_rlimit *r, int resource, const char *name) {
285
static int set_one_rlimit(const pa_rlimit *r, int resource, const char *name) {
285
286
struct rlimit rl;
291
292
rl.rlim_cur = rl.rlim_max = r->value;
293
if (setrlimit(resource, &rl) < 0)
294
if (setrlimit(resource, &rl) < 0) {
294
295
pa_log_warn("setrlimit(%s, (%u, %u)) failed: %s", name, (unsigned) r->value, (unsigned) r->value, pa_cstrerror(errno));
297
302
static void set_all_rlimits(const pa_daemon_conf *conf) {
371
383
* is just too risky tun let PA run as root all the time. */
386
/* At this point, we are a normal user, possibly with CAP_NICE if
387
* we were started SUID. If we are started as normal root, than we
388
* still are normal root. */
374
390
setlocale(LC_ALL, "");
376
if (suid_root && (pa_own_uid_in_group(PA_REALTIME_GROUP, &gid) <= 0)) {
377
pa_log_info("Warning: Called SUID root, but not in group '"PA_REALTIME_GROUP"'. "
378
"For enabling real-time scheduling please become a member of '"PA_REALTIME_GROUP"' , or increase the RLIMIT_RTPRIO user limit.");
381
suid_root = real_root = 0;
384
LTDL_SET_PRELOADED_SYMBOLS();
391
WSAStartup(MAKEWORD(2, 0), &data);
391
pa_log_set_maximal_level(PA_LOG_INFO);
397
392
pa_log_set_ident("pulseaudio");
399
394
conf = pa_daemon_conf_new();
407
402
if (pa_cmdline_parse(conf, argc, argv, &d) < 0) {
408
pa_log("failed to parse command line.");
403
pa_log("Failed to parse command line.");
412
407
pa_log_set_maximal_level(conf->log_level);
413
408
pa_log_set_target(conf->auto_log_target ? PA_LOG_STDERR : conf->log_target, NULL);
411
/* Ok, we're suid root, so let's better not enable high prio
412
* or RT by default */
414
allow_high_priority = allow_realtime = FALSE;
417
if (conf->high_priority) {
418
if (pa_polkit_check("org.pulseaudio.acquire-high-priority") > 0) {
419
pa_log_info("PolicyKit grants us acquire-high-priority privilige.");
420
allow_high_priority = TRUE;
422
pa_log_info("PolicyKit refuses acquire-high-priority privilige.");
425
if (conf->realtime_scheduling) {
426
if (pa_polkit_check("org.pulseaudio.acquire-real-time") > 0) {
427
pa_log_info("PolicyKit grants us acquire-real-time privilige.");
428
allow_realtime = TRUE;
430
pa_log_info("PolicyKit refuses acquire-real-time privilige.");
434
if ((conf->high_priority || conf->realtime_scheduling) && pa_own_uid_in_group(PA_REALTIME_GROUP, &gid) > 0) {
435
pa_log_info("We're in the group '"PA_REALTIME_GROUP"', allowing real-time and high-priority scheduling.");
436
allow_realtime = conf->realtime_scheduling;
437
allow_high_priority = conf->high_priority;
440
if (!allow_high_priority && !allow_realtime) {
442
/* OK, there's no further need to keep CAP_NICE. Hence
443
* let's give it up early */
447
suid_root = real_root = FALSE;
449
if (conf->high_priority || conf->realtime_scheduling)
450
pa_log_notice("Called SUID root and real-time/high-priority scheduling was requested in the configuration. However, we lack the necessary priviliges:\n"
451
"We are not in group '"PA_REALTIME_GROUP"' and PolicyKit refuse to grant us priviliges. Dropping SUID again.\n"
452
"For enabling real-time scheduling please acquire the appropriate PolicyKit priviliges, or become a member of '"PA_REALTIME_GROUP"', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this user.");
457
/* OK, we're a normal user, so let's allow the user evrything
458
* he asks for, it's now the kernel's job to enforce limits,
459
* not ours anymore */
460
allow_high_priority = allow_realtime = TRUE;
463
if (conf->high_priority && !allow_high_priority) {
464
pa_log_info("High-priority scheduling enabled in configuration but now allowed by policy. Disabling forcibly.");
465
conf->high_priority = FALSE;
468
if (conf->realtime_scheduling && !allow_realtime) {
469
pa_log_info("Real-time scheduling enabled in configuration but now allowed by policy. Disabling forcibly.");
470
conf->realtime_scheduling = FALSE;
415
473
if (conf->high_priority && conf->cmd == PA_CMD_DAEMON)
418
if (suid_root && (conf->cmd != PA_CMD_DAEMON || !conf->high_priority)) {
474
pa_raise_priority(conf->nice_level);
479
drop = conf->cmd != PA_CMD_DAEMON || !conf->realtime_scheduling;
484
/* At this point we still have CAP_NICE if we were loaded
485
* SUID root. If possible let's acquire RLIMIT_RTPRIO
486
* instead and give CAP_NICE up. */
488
const pa_rlimit rl = { 9, TRUE };
490
if (set_one_rlimit(&rl, RLIMIT_RTPRIO, "RLIMIT_RTPRIO") >= 0) {
491
pa_log_info("Successfully increased RLIMIT_RTPRIO, giving up CAP_NICE.");
494
pa_log_warn("RLIMIT_RTPRIO failed: %s", pa_cstrerror(errno));
501
suid_root = real_root = FALSE;
505
LTDL_SET_PRELOADED_SYMBOLS();
423
508
if (conf->dl_search_path)
424
509
lt_dlsetsearchpath(conf->dl_search_path);
514
WSAStartup(MAKEWORD(2, 0), &data);
426
520
switch (conf->cmd) {
427
521
case PA_CMD_DUMP_MODULES:
428
522
pa_dump_modules(conf, argc-d, argv+d);
632
726
c->is_system_instance = !!conf->system_instance;
633
c->high_priority = !!conf->high_priority;
634
727
c->default_sample_spec = conf->default_sample_spec;
635
728
c->default_n_fragments = conf->default_n_fragments;
636
729
c->default_fragment_size_msec = conf->default_fragment_size_msec;
637
c->disallow_module_loading = conf->disallow_module_loading;
638
730
c->exit_idle_time = conf->exit_idle_time;
639
731
c->module_idle_time = conf->module_idle_time;
640
732
c->scache_idle_time = conf->scache_idle_time;
641
733
c->resample_method = conf->resample_method;
734
c->realtime_priority = conf->realtime_priority;
735
c->realtime_scheduling = !!conf->realtime_scheduling;
736
c->disable_remixing = !!conf->disable_remixing;
643
738
pa_assert_se(pa_signal_init(pa_mainloop_get_api(mainloop)) == 0);
644
739
pa_signal_new(SIGINT, signal_callback, c);