Capability dropping when changing the user in the system
mode was previously implemented by calling
prctl(PR_SET_KEEPCAPS, 0), but that doesn't necessarily
work. It's possible that the KEEPCAPS flag is locked to 1,
in which case the prctl() call fails with EPERM (this
happens at least on Harmattan). This patch implements
explicit capability dropping after changing the user.
#include <sys/capability.h>
#endif
#include <sys/capability.h>
#endif
-#ifdef HAVE_SYS_PRCTL_H
-#include <sys/prctl.h>
-#endif
-
#include "caps.h"
/* Glibc <= 2.2 has broken unistd.h */
#include "caps.h"
/* Glibc <= 2.2 has broken unistd.h */
pa_assert_se(getegid() == gid);
#endif
pa_assert_se(getegid() == gid);
#endif
-#ifdef HAVE_SYS_PRCTL_H
- pa_assert_se(prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0) == 0);
-#endif
+ if (uid != 0)
+ pa_drop_caps();
+}
+void pa_drop_caps(void) {
#ifdef HAVE_SYS_CAPABILITY_H
#ifdef HAVE_SYS_CAPABILITY_H
- if (uid != 0) {
- 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);
- }
+ 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);
+#else
+ pa_log_warn("Normally all extra capabilities would be dropped now, but "
+ "that's impossible because this Pulseaudio was built without "
+ "libcap support.");
+void pa_drop_caps(void);
+
pa_set_env("USER", PA_SYSTEM_USER);
pa_set_env("USERNAME", PA_SYSTEM_USER);
pa_set_env("LOGNAME", PA_SYSTEM_USER);
pa_set_env("USER", PA_SYSTEM_USER);
pa_set_env("USERNAME", PA_SYSTEM_USER);
pa_set_env("LOGNAME", PA_SYSTEM_USER);
if (!getenv("PULSE_STATE_PATH"))
pa_set_env("PULSE_STATE_PATH", PA_SYSTEM_STATE_PATH);
if (!getenv("PULSE_STATE_PATH"))
pa_set_env("PULSE_STATE_PATH", PA_SYSTEM_STATE_PATH);
- pa_log_info(_("Successfully dropped root privileges."));
+ pa_log_info(_("Successfully changed user to \"" PA_SYSTEM_USER "\"."));