From 28405e3dcfba8b8b813678a79ca8194cccc7bb76 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 21 May 2008 22:50:58 +0000 Subject: big mumbo jumo of interleaved patches. * Use seperate "state" and "config" paths * Pass the fact that we are in system mode via an env var $PULSE_SYSTEM instead of as var in pa_core * Properly check proc name when checking PID files. Don't check exename, because we cannot read that for other uids git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@2480 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/main.c | 24 ++++++++-- src/modules/module-protocol-stub.c | 2 +- src/pulsecore/core.c | 1 - src/pulsecore/core.h | 1 - src/pulsecore/pid.c | 97 ++++++++++++++++++++++++++++---------- src/pulsecore/pid.h | 6 +-- src/pulsecore/protocol-native.c | 2 +- 7 files changed, 98 insertions(+), 35 deletions(-) diff --git a/src/daemon/main.c b/src/daemon/main.c index 789d104b..6e5997cf 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -202,6 +202,13 @@ static int change_user(void) { return -1; } + if (pa_make_secure_dir(PA_SYSTEM_STATE_PATH, 0700, pw->pw_uid, gr->gr_gid) < 0) { + pa_log("Failed to create '%s': %s", PA_SYSTEM_STATE_PATH, pa_cstrerror(errno)); + return -1; + } + + /* We don't create the config dir here, because we don't need to write to it */ + if (initgroups(PA_SYSTEM_USER, gr->gr_gid) != 0) { pa_log("Failed to change group list: %s", pa_cstrerror(errno)); return -1; @@ -246,7 +253,8 @@ static int change_user(void) { /* Relevant for pa_runtime_path() */ pa_set_env("PULSE_RUNTIME_PATH", PA_SYSTEM_RUNTIME_PATH); - pa_set_env("PULSE_CONFIG_PATH", PA_SYSTEM_RUNTIME_PATH); + pa_set_env("PULSE_CONFIG_PATH", PA_SYSTEM_CONFIG_PATH); + pa_set_env("PULSE_STATE_PATH", PA_SYSTEM_STATE_PATH); pa_log_info("Successfully dropped root privileges."); @@ -705,13 +713,22 @@ int main(int argc, char *argv[]) { if (change_user() < 0) goto finish; + pa_set_env("PULSE_SYSTEM", conf->system_instance ? "1" : "0"); + pa_log_info("This is PulseAudio " PACKAGE_VERSION); pa_log_info("Page size is %lu bytes", (unsigned long) PA_PAGE_SIZE); - pa_log_info("Using runtime directory %s.", s = pa_get_runtime_dir()); + if (!(s = pa_get_runtime_dir())) + goto finish; + pa_log_info("Using runtime directory %s.", s); pa_xfree(s); + if (!(s = pa_get_state_dir())) + pa_log_info("Using state directory %s.", s); + pa_xfree(s); + + pa_log_info("Running in system mode: %s", pa_yes_no(pa_in_system_mode())); if (conf->use_pid_file) { - if (pa_pid_file_create() < 0) { + if (pa_pid_file_create("pulseaudio") < 0) { pa_log("pa_pid_file_create() failed."); goto finish; } @@ -740,7 +757,6 @@ int main(int argc, char *argv[]) { goto finish; } - c->is_system_instance = !!conf->system_instance; c->default_sample_spec = conf->default_sample_spec; c->default_n_fragments = conf->default_n_fragments; c->default_fragment_size_msec = conf->default_fragment_size_msec; diff --git a/src/modules/module-protocol-stub.c b/src/modules/module-protocol-stub.c index 8bcc19b1..ca7a6c51 100644 --- a/src/modules/module-protocol-stub.c +++ b/src/modules/module-protocol-stub.c @@ -271,7 +271,7 @@ int pa__init(pa_module*m) { /* This socket doesn't reside in our own runtime dir but in * /tmp/.esd/, hence we have to create the dir first */ - if (pa_make_secure_parent_dir(u->socket_path, m->core->is_system_instance ? 0755 : 0700, (uid_t)-1, (gid_t)-1) < 0) { + if (pa_make_secure_parent_dir(u->socket_path, pa_in_system_mode() ? 0755 : 0700, (uid_t)-1, (gid_t)-1) < 0) { pa_log("Failed to create socket directory '%s': %s\n", u->socket_path, pa_cstrerror(errno)); goto fail; } diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c index 3b758a38..a1bd0204 100644 --- a/src/pulsecore/core.c +++ b/src/pulsecore/core.c @@ -135,7 +135,6 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) { c->resample_method = PA_RESAMPLER_SPEEX_FLOAT_BASE + 3; - c->is_system_instance = FALSE; c->disallow_module_loading = FALSE; c->realtime_scheduling = FALSE; c->realtime_priority = 5; diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h index 50c05b4c..77e8f9ff 100644 --- a/src/pulsecore/core.h +++ b/src/pulsecore/core.h @@ -123,7 +123,6 @@ struct pa_core { pa_bool_t disallow_module_loading, running_as_daemon; pa_resample_method_t resample_method; - pa_bool_t is_system_instance; pa_bool_t realtime_scheduling; int realtime_priority; pa_bool_t disable_remixing; diff --git a/src/pulsecore/pid.c b/src/pulsecore/pid.c index 2ff132bb..9e93234f 100644 --- a/src/pulsecore/pid.c +++ b/src/pulsecore/pid.c @@ -140,8 +140,51 @@ fail: return -1; } +static int proc_name_ours(pid_t pid, const char *procname) { +#ifdef __linux__ + char bn[PATH_MAX]; + FILE *f; + + pa_snprintf(bn, sizeof(bn), "/proc/%lu/stat", (unsigned long) pid); + + if (!(f = fopen(bn, "r"))) { + pa_log_info("Failed to open %s: %s", bn, pa_cstrerror(errno)); + return -1; + } else { + char *expected; + pa_bool_t good; + char stored[64]; + + if (!(fgets(stored, sizeof(stored), f))) { + pa_log_info("Failed to read from %s: %s", bn, feof(f) ? "EOF" : pa_cstrerror(errno)); + fclose(f); + return -1; + } + + fclose(f); + + expected = pa_sprintf_malloc("%lu (%s)", (unsigned long) pid, procname); + good = pa_startswith(stored, expected); + pa_xfree(expected); + +#if !defined(__OPTIMIZE__) + if (!good) { + /* libtool likes to rename our binary names ... */ + expected = pa_sprintf_malloc("%lu (lt-%s)", (unsigned long) pid, procname); + good = pa_startswith(stored, expected); + pa_xfree(expected); + } +#endif + + return !!good; + } +#endif + + return 1; +} + /* Create a new PID file for the current process. */ -int pa_pid_file_create(void) { +int pa_pid_file_create(const char *procname) { int fd = -1; int ret = -1; char t[20]; @@ -153,7 +196,8 @@ int pa_pid_file_create(void) { HANDLE process; #endif - fn = pa_runtime_path("pid"); + if (!(fn = pa_runtime_path("pid"))) + goto fail; if ((fd = open_pid_file(fn, O_CREAT|O_RDWR)) < 0) goto fail; @@ -161,14 +205,23 @@ int pa_pid_file_create(void) { if ((pid = read_pid(fn, fd)) == (pid_t) -1) pa_log_warn("Corrupt PID file, overwriting."); else if (pid > 0) { + #ifdef OS_IS_WIN32 if ((process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid)) != NULL) { CloseHandle(process); #else if (kill(pid, 0) >= 0 || errno != ESRCH) { #endif - pa_log("Daemon already running."); - goto fail; + int ours = 1; + + if (procname) + if ((ours = proc_name_ours(pid, procname)) < 0) + goto fail; + + if (ours) { + pa_log("Daemon already running."); + goto fail; + } } pa_log_warn("Stale PID file, overwriting."); @@ -212,7 +265,8 @@ int pa_pid_file_remove(void) { int ret = -1; pid_t pid; - fn = pa_runtime_path("pid"); + if (!(fn = pa_runtime_path("pid"))) + goto fail; if ((fd = open_pid_file(fn, O_RDWR)) < 0) { pa_log_warn("Failed to open PID file '%s': %s", fn, pa_cstrerror(errno)); @@ -234,7 +288,7 @@ int pa_pid_file_remove(void) { #ifdef OS_IS_WIN32 pa_lock_fd(fd, 0); - close(fd); + pa_close(fd); fd = -1; #endif @@ -265,8 +319,8 @@ fail: * exists and the PID therein too. Returns 0 on succcess, -1 * otherwise. If pid is non-NULL and a running daemon was found, * return its PID therein */ -int pa_pid_file_check_running(pid_t *pid, const char *binary_name) { - return pa_pid_file_kill(0, pid, binary_name); +int pa_pid_file_check_running(pid_t *pid, const char *procname) { + return pa_pid_file_kill(0, pid, procname); } #ifndef OS_IS_WIN32 @@ -274,7 +328,7 @@ int pa_pid_file_check_running(pid_t *pid, const char *binary_name) { /* Kill a current running daemon. Return non-zero on success, -1 * otherwise. If successful *pid contains the PID of the daemon * process. */ -int pa_pid_file_kill(int sig, pid_t *pid, const char *binary_name) { +int pa_pid_file_kill(int sig, pid_t *pid, const char *procname) { int fd = -1; char *fn; int ret = -1; @@ -282,10 +336,12 @@ int pa_pid_file_kill(int sig, pid_t *pid, const char *binary_name) { #ifdef __linux__ char *e = NULL; #endif + if (!pid) pid = &_pid; - fn = pa_runtime_path("pid"); + if (!(fn = pa_runtime_path("pid"))) + goto fail; if ((fd = open_pid_file(fn, O_RDONLY)) < 0) goto fail; @@ -293,22 +349,15 @@ int pa_pid_file_kill(int sig, pid_t *pid, const char *binary_name) { if ((*pid = read_pid(fn, fd)) == (pid_t) -1) goto fail; -#ifdef __linux__ - if (binary_name) { - pa_snprintf(fn, sizeof(fn), "/proc/%lu/exe", (unsigned long) pid); + if (procname) { + int ours; - if ((e = pa_readlink(fn))) { - char *f = pa_path_get_filename(e); - if (strcmp(f, binary_name) -#if !defined(__OPTIMIZE__) - /* libtool likes to rename our binary names ... */ - && !(pa_startswith(f, "lt-") && strcmp(f+3, binary_name) == 0) -#endif - ) - goto fail; - } + if ((ours = proc_name_ours(*pid, procname)) < 0) + goto fail; + + if (!ours) + goto fail; } -#endif ret = kill(*pid, sig); diff --git a/src/pulsecore/pid.h b/src/pulsecore/pid.h index 1d6de7b5..af407191 100644 --- a/src/pulsecore/pid.h +++ b/src/pulsecore/pid.h @@ -24,9 +24,9 @@ USA. ***/ -int pa_pid_file_create(void); +int pa_pid_file_create(const char *procname); int pa_pid_file_remove(void); -int pa_pid_file_check_running(pid_t *pid, const char *binary_name); -int pa_pid_file_kill(int sig, pid_t *pid, const char *binary_name); +int pa_pid_file_check_running(pid_t *pid, const char *procname); +int pa_pid_file_kill(int sig, pid_t *pid, const char *procname); #endif diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 6178a232..10632986 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -4009,7 +4009,7 @@ static pa_protocol_native* protocol_new_internal(pa_core *c, pa_module *m, pa_mo pa_log("auth-group-enabled= expects a boolean argument."); return NULL; } - p->auth_group = a ? pa_xstrdup(pa_modargs_get_value(ma, "auth-group", c->is_system_instance ? PA_ACCESS_GROUP : NULL)) : NULL; + p->auth_group = a ? pa_xstrdup(pa_modargs_get_value(ma, "auth-group", pa_in_system_mode() ? PA_ACCESS_GROUP : NULL)) : NULL; if (p->auth_group) pa_log_info("Allowing access to group '%s'.", p->auth_group); -- cgit