]> code.delx.au - pulseaudio/commitdiff
daemon: Don't rely on prctl(PR_SET_KEEPCAPS, 0) for dropping caps.
authorTanu Kaskinen <tanu.kaskinen@digia.com>
Thu, 5 Apr 2012 12:37:19 +0000 (15:37 +0300)
committerTanu Kaskinen <tanuk@iki.fi>
Thu, 7 Feb 2013 09:59:58 +0000 (11:59 +0200)
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.

src/daemon/caps.c
src/daemon/caps.h
src/daemon/main.c

index 37593880500c798eef6cada718e3f4aa8e7ea5bb..36b76a90acfb22a410f409699001bbbfca8f2b91 100644 (file)
 #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 */
@@ -78,17 +74,20 @@ void pa_drop_root(void) {
     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
-    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.");
 #endif
 }
index 5d0ee62e0bc1721909868d9f1272309fdcdcd3e9..e9cd7cb36d3901d01b89213978e3826cd51f4d08 100644 (file)
@@ -26,4 +26,6 @@
 
 void pa_drop_root(void);
 
+void pa_drop_caps(void);
+
 #endif
index f7b102d4d5e1d08e32ffe01a2fcf551bab265585..c18524ffb1c71b2f5c19b17c5e4e5b8adfd16249 100644 (file)
@@ -251,6 +251,8 @@ static int change_user(void) {
         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);
@@ -266,7 +268,7 @@ static int change_user(void) {
     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 "\"."));
 
     return 0;
 }