summaryrefslogtreecommitdiffstats
path: root/src/daemon
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2007-05-25 20:35:30 +0000
committerLennart Poettering <lennart@poettering.net>2007-05-25 20:35:30 +0000
commit4d88fcd59da84ac4f09113855c8f15384a4e05c3 (patch)
treee144296f3a041204bbf15f90af0164707c8ffde1 /src/daemon
parent65e87616833252884e4ab6b87373f98939fc446a (diff)
when called with the setid bit change euid to uid sooner to make sure that we can access our own files even when we dropped most capabilities. (Closes #21)
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1455 fefdeb5f-60dc-0310-8127-8f9354f1896f
Diffstat (limited to 'src/daemon')
-rw-r--r--src/daemon/caps.c33
-rw-r--r--src/daemon/main.c29
2 files changed, 33 insertions, 29 deletions
diff --git a/src/daemon/caps.c b/src/daemon/caps.c
index 2ea51c9f..8043230c 100644
--- a/src/daemon/caps.c
+++ b/src/daemon/caps.c
@@ -35,6 +35,9 @@
#ifdef HAVE_SYS_CAPABILITY_H
#include <sys/capability.h>
#endif
+#ifdef HAVE_SYS_PRCTL_H
+#include <sys/prctl.h>
+#endif
#include <pulsecore/core-error.h>
@@ -76,35 +79,31 @@ void pa_drop_root(void) {
#endif
-#ifdef HAVE_SYS_CAPABILITY_H
+#if defined(HAVE_SYS_CAPABILITY_H) && defined(HAVE_SYS_PRCTL_H)
-/* Limit capabilities set to CAPSYS_NICE */
+/* Limit permitted capabilities set to CAPSYS_NICE */
int pa_limit_caps(void) {
int r = -1;
cap_t caps;
cap_value_t nice_cap = CAP_SYS_NICE;
- /* Only drop caps when called SUID */
- if (getuid() == 0)
- return 0;
-
caps = cap_init();
assert(caps);
-
cap_clear(caps);
-
- cap_set_flag(caps, CAP_EFFECTIVE, 1, &nice_cap, CAP_SET);
cap_set_flag(caps, CAP_PERMITTED, 1, &nice_cap, CAP_SET);
if (cap_set_proc(caps) < 0)
goto fail;
+ if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0)
+ goto fail;
+
pa_log_info("dropped capabilities successfully.");
-
- r = 0;
+
+ r = 1;
fail:
- cap_free (caps);
+ cap_free(caps);
return r;
}
@@ -114,24 +113,22 @@ int pa_drop_caps(void) {
cap_t caps;
int r = -1;
- /* Only drop caps when called SUID */
- if (getuid() == 0)
- return 0;
-
caps = cap_init();
assert(caps);
cap_clear(caps);
+ prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0);
+
if (cap_set_proc(caps) < 0) {
pa_log("failed to drop capabilities: %s", pa_cstrerror(errno));
goto fail;
}
-
+
r = 0;
fail:
- cap_free (caps);
+ cap_free(caps);
return r;
}
diff --git a/src/daemon/main.c b/src/daemon/main.c
index 211dd30c..72e47975 100644
--- a/src/daemon/main.c
+++ b/src/daemon/main.c
@@ -329,22 +329,29 @@ int main(int argc, char *argv[]) {
struct timeval tv;
#endif
- setlocale(LC_ALL, "");
-
- pa_limit_caps();
-
#ifdef HAVE_GETUID
real_root = getuid() == 0;
suid_root = !real_root && geteuid() == 0;
+#else
+ real_root = 0;
+ suid_root = 0;
+#endif
+
+ if (suid_root) {
+ if (pa_limit_caps() > 0)
+ /* We managed to drop capabilities except the needed
+ * ones. Hence we can drop the uid. */
+ pa_drop_root();
+ }
+
+ setlocale(LC_ALL, "");
if (suid_root && (pa_own_uid_in_group(PA_REALTIME_GROUP, &gid) <= 0 || gid >= 1000)) {
pa_log_warn("WARNING: called SUID root, but not in group '"PA_REALTIME_GROUP"'.");
+ pa_drop_caps();
pa_drop_root();
+ suid_root = real_root = 0;
}
-#else
- real_root = 0;
- suid_root = 0;
-#endif
LTDL_SET_PRELOADED_SYMBOLS();
@@ -381,10 +388,10 @@ int main(int argc, char *argv[]) {
if (conf->high_priority && conf->cmd == PA_CMD_DAEMON)
pa_raise_priority();
- pa_drop_caps();
-
- if (suid_root)
+ if (suid_root) {
+ pa_drop_caps();
pa_drop_root();
+ }
if (conf->dl_search_path)
lt_dlsetsearchpath(conf->dl_search_path);