diff --git a/src/daemon/caps.c b/src/daemon/caps.c index fd135c0d2..e68e0a69b 100644 --- a/src/daemon/caps.c +++ b/src/daemon/caps.c @@ -36,64 +36,11 @@ #include "caps.h" -/* Glibc <= 2.2 has broken unistd.h */ -#if defined(__linux__) && (__GLIBC__ <= 2 && __GLIBC_MINOR__ <= 2) -int setresgid(gid_t r, gid_t e, gid_t s); -int setresuid(uid_t r, uid_t e, uid_t s); -#endif - -/* Drop root rights when called SUID root */ +/* Disable privilege dropping on Android. */ void pa_drop_root(void) { - -#ifdef HAVE_GETUID - uid_t uid; - gid_t gid; - - pa_log_debug("Cleaning up privileges."); - uid = getuid(); - gid = getgid(); - -#if defined(HAVE_SETRESUID) - pa_assert_se(setresuid(uid, uid, uid) >= 0); - pa_assert_se(setresgid(gid, gid, gid) >= 0); -#elif defined(HAVE_SETREUID) - pa_assert_se(setreuid(uid, uid) >= 0); - pa_assert_se(setregid(gid, gid) >= 0); -#else - pa_assert_se(setuid(uid) >= 0); - pa_assert_se(seteuid(uid) >= 0); - pa_assert_se(setgid(gid) >= 0); - pa_assert_se(setegid(gid) >= 0); -#endif - - pa_assert_se(getuid() == uid); - pa_assert_se(geteuid() == uid); - pa_assert_se(getgid() == gid); - pa_assert_se(getegid() == gid); - - if (uid != 0) - pa_drop_caps(); -#endif + return; } void pa_drop_caps(void) { -#ifdef HAVE_SYS_CAPABILITY_H -#if defined(__linux__) - cap_t caps; - pa_assert_se(caps = cap_init()); - pa_assert_se(cap_clear(caps) == 0); - pa_assert_se(cap_set_proc(caps) == 0); - pa_assert_se(cap_free(caps) == 0); -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - /* FreeBSD doesn't have this functionality, even though sys/capability.h is - * available. See https://bugs.freedesktop.org/show_bug.cgi?id=72580 */ - pa_log_warn("FreeBSD cannot drop extra capabilities, implementation needed."); -#else -#error "Don't know how to do capabilities on your system. Please send a patch." -#endif /* __linux__ */ -#else /* HAVE_SYS_CAPABILITY_H */ - pa_log_warn("Normally all extra capabilities would be dropped now, but " - "that's impossible because PulseAudio was built without " - "capabilities support."); -#endif + return; } diff --git a/src/daemon/main.c b/src/daemon/main.c index 924a4d4aa..80130e056 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -163,206 +163,11 @@ static void signal_callback(pa_mainloop_api* m, pa_signal_event *e, int sig, voi } -#if defined(OS_IS_WIN32) - +// Disable privilege dropping on Android. static int change_user(void) { - pa_log_info("Overriding system runtime/config base dir to '%s'.", pa_win32_get_system_appdata()); - - /* On other platforms, these paths are compiled into PulseAudio. This isn't - * suitable on Windows. Firstly, Windows doesn't follow the FHS or use Unix - * paths and the build system can't handle Windows-style paths properly. - * Secondly, the idiomatic location for a service's state and shared data is - * ProgramData, and the location of special folders is dynamic on Windows. - * Also, this method of handling paths is consistent with how they are - * handled on Windows in other parts of PA. Note that this is only needed - * in system-wide mode since paths in user instances are already handled - * properly. - */ - - char *run_path = pa_sprintf_malloc("%s" PA_PATH_SEP "run", pa_win32_get_system_appdata()); - char *lib_path = pa_sprintf_malloc("%s" PA_PATH_SEP "lib", pa_win32_get_system_appdata()); - - /* https://docs.microsoft.com/en-us/windows/win32/secauthz/ace-strings */ - /* https://docs.microsoft.com/en-us/windows/win32/secauthz/modifying-the-acls-of-an-object-in-c-- */ - /* https://docs.microsoft.com/en-us/windows/win32/api/sddl/nf-sddl-convertstringsecuritydescriptortosecuritydescriptora */ - { - mkdir(run_path); - PSECURITY_DESCRIPTOR sd; - if (ConvertStringSecurityDescriptorToSecurityDescriptorA( - "D:PAI" /* DACL, disable inheritance from parent, enable propagation to children */ - "(A;OICI;FA;;;SY)" /* give system full access */ - "(A;OICI;FA;;;CO)" /* give owner full access */ - "(A;OICI;FA;;;BA)" /* give administrators full access */ - "(A;OICI;0x1200a9;;;WD)", /* give everyone read/write/execute access */ - SDDL_REVISION_1, &sd, NULL - )) { - PACL acl; - BOOL acl_present, acl_default; - if (GetSecurityDescriptorDacl(sd, &acl_present, &acl, &acl_default)) { - if (SetNamedSecurityInfo(run_path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION, NULL, NULL, acl, NULL) != ERROR_SUCCESS) { - pa_log_warn("Failed to set DACL for runtime dir: failed to apply DACL: error %lu.", GetLastError()); - } - LocalFree(acl); - } else { - pa_log_warn("Failed to set DACL for runtime dir: failed to get security descriptor DACL: error %lu.", GetLastError()); - } - } else { - pa_log_warn("Failed to set DACL for runtime dir: failed to parse security descriptor: error %lu.", GetLastError()); - } - } - { - mkdir(lib_path); - PSECURITY_DESCRIPTOR sd; - if (ConvertStringSecurityDescriptorToSecurityDescriptorA( - "D:PAI" /* DACL, disable inheritance from parent, enable propagation to children */ - "(A;OICI;FA;;;SY)" /* give system full access */ - "(A;OICI;FA;;;CO)" /* give owner full access */ - "(A;OICI;FA;;;BA)", /* give administrators full access */ - SDDL_REVISION_1, &sd, NULL - )) { - PACL acl; - BOOL acl_present, acl_default; - if (GetSecurityDescriptorDacl(sd, &acl_present, &acl, &acl_default)) { - if (SetNamedSecurityInfo(lib_path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION, NULL, NULL, acl, NULL) != ERROR_SUCCESS) { - pa_log_warn("Failed to set DACL for lib dir: failed to apply DACL: error %lu.", GetLastError()); - } - LocalFree(acl); - } else { - pa_log_warn("Failed to set DACL for lib dir: failed to get security descriptor DACL: error %lu.", GetLastError()); - } - } else { - pa_log_warn("Failed to set DACL for lib dir: failed to parse security descriptor: error %lu.", GetLastError()); - } - } - - pa_set_env("HOME", run_path); - if (!getenv("PULSE_RUNTIME_PATH")) - pa_set_env("PULSE_RUNTIME_PATH", run_path); - if (!getenv("PULSE_CONFIG_PATH")) - pa_set_env("PULSE_CONFIG_PATH", lib_path); - if (!getenv("PULSE_STATE_PATH")) - pa_set_env("PULSE_STATE_PATH", lib_path); - - pa_xfree(run_path); - pa_xfree(lib_path); - - pa_log_info("Not changing user for system instance on Windows."); return 0; } -#elif defined(HAVE_PWD_H) && defined(HAVE_GRP_H) - -static int change_user(void) { - struct passwd *pw; - struct group * gr; - int r; - - /* This function is called only in system-wide mode. It creates a - * runtime dir in /var/run/ with proper UID/GID and drops privs - * afterwards. */ - - if (!(pw = getpwnam(PA_SYSTEM_USER))) { - pa_log(_("Failed to find user '%s'."), PA_SYSTEM_USER); - return -1; - } - - if (!(gr = getgrnam(PA_SYSTEM_GROUP))) { - pa_log(_("Failed to find group '%s'."), PA_SYSTEM_GROUP); - return -1; - } - - pa_log_info("Found user '%s' (UID %lu) and group '%s' (GID %lu).", - PA_SYSTEM_USER, (unsigned long) pw->pw_uid, - PA_SYSTEM_GROUP, (unsigned long) gr->gr_gid); - - if (pw->pw_gid != gr->gr_gid) { - pa_log(_("GID of user '%s' and of group '%s' don't match."), PA_SYSTEM_USER, PA_SYSTEM_GROUP); - return -1; - } - - if (!pa_streq(pw->pw_dir, PA_SYSTEM_RUNTIME_PATH)) - pa_log_warn(_("Home directory of user '%s' is not '%s', ignoring."), PA_SYSTEM_USER, PA_SYSTEM_RUNTIME_PATH); - - if (pa_make_secure_dir(PA_SYSTEM_RUNTIME_PATH, 0755, pw->pw_uid, gr->gr_gid, true) < 0) { - pa_log(_("Failed to create '%s': %s"), PA_SYSTEM_RUNTIME_PATH, pa_cstrerror(errno)); - return -1; - } - - if (pa_make_secure_dir(PA_SYSTEM_STATE_PATH, 0700, pw->pw_uid, gr->gr_gid, true) < 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; - } - -#if defined(HAVE_SETRESGID) - r = setresgid(gr->gr_gid, gr->gr_gid, gr->gr_gid); -#elif defined(HAVE_SETEGID) - if ((r = setgid(gr->gr_gid)) >= 0) - r = setegid(gr->gr_gid); -#elif defined(HAVE_SETREGID) - r = setregid(gr->gr_gid, gr->gr_gid); -#else -#error "No API to drop privileges" -#endif - - if (r < 0) { - pa_log(_("Failed to change GID: %s"), pa_cstrerror(errno)); - return -1; - } - -#if defined(HAVE_SETRESUID) - r = setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid); -#elif defined(HAVE_SETEUID) - if ((r = setuid(pw->pw_uid)) >= 0) - r = seteuid(pw->pw_uid); -#elif defined(HAVE_SETREUID) - r = setreuid(pw->pw_uid, pw->pw_uid); -#else -#error "No API to drop privileges" -#endif - - if (r < 0) { - pa_log(_("Failed to change UID: %s"), pa_cstrerror(errno)); - return -1; - } - - pa_drop_caps(); - - pa_set_env("USER", PA_SYSTEM_USER); - pa_set_env("USERNAME", PA_SYSTEM_USER); - pa_set_env("LOGNAME", PA_SYSTEM_USER); - pa_set_env("HOME", PA_SYSTEM_RUNTIME_PATH); - - /* Relevant for pa_runtime_path() */ - if (!getenv("PULSE_RUNTIME_PATH")) - pa_set_env("PULSE_RUNTIME_PATH", PA_SYSTEM_RUNTIME_PATH); - - if (!getenv("PULSE_CONFIG_PATH")) - pa_set_env("PULSE_CONFIG_PATH", PA_SYSTEM_CONFIG_PATH); - - if (!getenv("PULSE_STATE_PATH")) - pa_set_env("PULSE_STATE_PATH", PA_SYSTEM_STATE_PATH); - - pa_log_info("Successfully changed user to \"" PA_SYSTEM_USER "\"."); - - return 0; -} - -#else /* HAVE_PWD_H && HAVE_GRP_H */ - -static int change_user(void) { - pa_log(_("System wide mode unsupported on this platform.")); - return -1; -} - -#endif /* HAVE_PWD_H && HAVE_GRP_H */ - #ifdef HAVE_SYS_RESOURCE_H static int set_one_rlimit(const pa_rlimit *r, int resource, const char *name) {