chiark / gitweb /
execute: when we run as PID 1 the kernel doesn't give us CAP_SETPCAP by default....
authorLennart Poettering <lennart@poettering.net>
Tue, 19 Apr 2011 04:06:41 +0000 (06:06 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 19 Apr 2011 04:06:41 +0000 (06:06 +0200)
TODO
src/execute.c

diff --git a/TODO b/TODO
index 80faf0fa3f17a641f26e421afb1b05475d4103f9..b4a5e3ab94d47e92b438dae07318f0809ac7f8fd 100644 (file)
--- a/TODO
+++ b/TODO
@@ -32,8 +32,16 @@ F15:
 * don't trim empty cgroups
   https://bugzilla.redhat.com/show_bug.cgi?id=678555
 
+* drop cap bounding set in logger, hostnamed, readahead, ...
+
+* timeout value is incorrectly parsed in /etc/fstab
+
 Features:
 
+* Add ListenSpecial to .socket units for /proc/kmsg and similar friends?
+
+* avoid DefaultStandardOutput=syslog to have any effect on StandardInput=socket services
+
 * use pivot_root on shutdown so that we can unmount the root directory.
 
 * fix alsa mixer restore to not print error when no config is stored
@@ -43,8 +51,11 @@ Features:
 * write blog stories about:
   - enabling dbus services
   - status update
+  - the new configuration files
   - you are a distro: why switch?
 
+* maybe add tiny dbus services similar to hostnamed for locale?
+
 * allow port = 0 in .socket units
 
 * rename systemd-logger to systemd-stdio-syslog-bridge
index 1e376ff89e08beacdf46aa344e3a2128f9bde6ac..745dcfcdb8526d76c8c981546ebf756f91b99a03 100644 (file)
@@ -904,6 +904,68 @@ fail:
 }
 #endif
 
+static int do_capability_bounding_set_drop(uint64_t drop) {
+        unsigned long i;
+        cap_t old_cap = NULL, new_cap = NULL;
+        cap_flag_value_t fv;
+        int r;
+
+        /* If we are run as PID 1 we will lack CAP_SETPCAP by default
+         * in the effective set (yes, the kernel drops that when
+         * executing init!), so get it back temporarily so that we can
+         * call PR_CAPBSET_DROP. */
+
+        old_cap = cap_get_proc();
+        if (!old_cap)
+                return -errno;
+
+        if (cap_get_flag(old_cap, CAP_SETPCAP, CAP_EFFECTIVE, &fv) < 0) {
+                r = -errno;
+                goto finish;
+        }
+
+        if (fv != CAP_SET) {
+                static const cap_value_t v = CAP_SETPCAP;
+
+                new_cap = cap_dup(old_cap);
+                if (!new_cap) {
+                        r = -errno;
+                        goto finish;
+                }
+
+                if (cap_set_flag(new_cap, CAP_EFFECTIVE, 1, &v, CAP_SET) < 0) {
+                        r = -errno;
+                        goto finish;
+                }
+
+                if (cap_set_proc(new_cap) < 0) {
+                        r = -errno;
+                        goto finish;
+                }
+        }
+
+        for (i = 0; i <= CAP_LAST_CAP; i++)
+                if (drop & ((uint64_t) 1ULL << (uint64_t) i)) {
+                        if (prctl(PR_CAPBSET_DROP, i) < 0) {
+                                r = -errno;
+                                goto finish;
+                        }
+                }
+
+        r = 0;
+
+finish:
+        if (new_cap)
+                cap_free(new_cap);
+
+        if (old_cap) {
+                cap_set_proc(old_cap);
+                cap_free(old_cap);
+        }
+
+        return r;
+}
+
 int exec_spawn(ExecCommand *command,
                char **argv,
                const ExecContext *context,
@@ -1251,13 +1313,10 @@ int exec_spawn(ExecCommand *command,
                         }
 
                         if (context->capability_bounding_set_drop)
-                                for (i = 0; i <= CAP_LAST_CAP; i++)
-                                        if (context->capability_bounding_set_drop & ((uint64_t) 1ULL << (uint64_t) i)) {
-                                                if (prctl(PR_CAPBSET_DROP, i) < 0) {
-                                                        r = EXIT_CAPABILITIES;
-                                                        goto fail_child;
-                                                }
-                                        }
+                                if (do_capability_bounding_set_drop(context->capability_bounding_set_drop) < 0) {
+                                        r = EXIT_CAPABILITIES;
+                                        goto fail_child;
+                                }
 
                         if (context->user)
                                 if (enforce_user(context, uid) < 0) {