[systemd-commits] 2 commits - src/journal src/shared

Lennart Poettering lennart at kemper.freedesktop.org
Wed Jan 28 17:48:01 PST 2015


 src/journal/coredump.c   |   21 +++++++++++----------
 src/journal/sd-journal.c |    7 +++++++
 src/shared/capability.c  |   30 ++++++++++++++++--------------
 3 files changed, 34 insertions(+), 24 deletions(-)

New commits:
commit f11943c53ec181829a821c6b27acf828bab71caa
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jan 29 02:47:29 2015 +0100

    coredump: drop caps while we are processing the coredump
    
    https://bugs.freedesktop.org/show_bug.cgi?id=87354

diff --git a/src/journal/coredump.c b/src/journal/coredump.c
index d322e79..f6b9514 100644
--- a/src/journal/coredump.c
+++ b/src/journal/coredump.c
@@ -31,9 +31,8 @@
 #  include <elfutils/libdwfl.h>
 #endif
 
-#include "systemd/sd-journal.h"
-#include "systemd/sd-login.h"
-
+#include "sd-journal.h"
+#include "sd-login.h"
 #include "log.h"
 #include "util.h"
 #include "fileio.h"
@@ -42,14 +41,15 @@
 #include "mkdir.h"
 #include "special.h"
 #include "cgroup-util.h"
-#include "journald-native.h"
 #include "conf-parser.h"
 #include "copy.h"
 #include "stacktrace.h"
 #include "path-util.h"
 #include "compress.h"
-#include "coredump-vacuum.h"
 #include "acl-util.h"
+#include "capability.h"
+#include "journald-native.h"
+#include "coredump-vacuum.h"
 
 /* The maximum size up to which we process coredumps */
 #define PROCESS_SIZE_MAX ((off_t) (2LLU*1024LLU*1024LLU*1024LLU))
@@ -810,11 +810,12 @@ int main(int argc, char* argv[]) {
          * segfaulted process and allocate the coredump memory under
          * the user's uid. This also ensures that the credentials
          * journald will see are the ones of the coredumping user,
-         * thus making sure the user gets access to the core dump. */
-        if (setresgid(gid, gid, gid) < 0 ||
-            setresuid(uid, uid, uid) < 0) {
-                log_error_errno(errno, "Failed to drop privileges: %m");
-                r = -errno;
+         * thus making sure the user gets access to the core
+         * dump. Let's also get rid of all capabilities, if we run as
+         * root, we won't need them anymore. */
+        r = drop_privileges(uid, gid, 0);
+        if (r < 0) {
+                log_error_errno(r, "Failed to drop privileges: %m");
                 goto finish;
         }
 
diff --git a/src/shared/capability.c b/src/shared/capability.c
index b1be043..b39e8e2 100644
--- a/src/shared/capability.c
+++ b/src/shared/capability.c
@@ -230,8 +230,9 @@ int capability_bounding_set_drop_usermode(uint64_t drop) {
 }
 
 int drop_privileges(uid_t uid, gid_t gid, uint64_t keep_capabilities) {
-
+        cap_value_t bits[sizeof(keep_capabilities)*8];
         _cleanup_cap_free_ cap_t d = NULL;
+        unsigned i, j = 0;
         int r;
 
         /* Unfortunately we cannot leave privilege dropping to PID 1
@@ -247,7 +248,8 @@ int drop_privileges(uid_t uid, gid_t gid, uint64_t keep_capabilities) {
         if (setgroups(0, NULL) < 0)
                 return log_error_errno(errno, "Failed to drop auxiliary groups list: %m");
 
-        if (prctl(PR_SET_KEEPCAPS, 1) < 0)
+        /* Ensure we keep the permitted caps across the setresuid(), if we need them */
+        if (prctl(PR_SET_KEEPCAPS, keep_capabilities != 0) < 0)
                 return log_error_errno(errno, "Failed to enable keep capabilities flag: %m");
 
         r = setresuid(uid, uid, uid);
@@ -257,27 +259,27 @@ int drop_privileges(uid_t uid, gid_t gid, uint64_t keep_capabilities) {
         if (prctl(PR_SET_KEEPCAPS, 0) < 0)
                 return log_error_errno(errno, "Failed to disable keep capabilities flag: %m");
 
+        /* Drop all caps from the bounding set, except the ones we want */
         r = capability_bounding_set_drop(~keep_capabilities, true);
         if (r < 0)
                 return log_error_errno(r, "Failed to drop capabilities: %m");
 
+        if (keep_capabilities == 0) /* All is gone, we can exit early */
+                return 0;
+
+        /* Now upgrade the permitted caps we still kept to effective caps */
         d = cap_init();
         if (!d)
                 return log_oom();
 
-        if (keep_capabilities) {
-                cap_value_t bits[sizeof(keep_capabilities)*8];
-                unsigned i, j = 0;
+        for (i = 0; i < sizeof(keep_capabilities)*8; i++)
+                if (keep_capabilities & (1ULL << i))
+                        bits[j++] = i;
 
-                for (i = 0; i < sizeof(keep_capabilities)*8; i++)
-                        if (keep_capabilities & (1ULL << i))
-                                bits[j++] = i;
-
-                if (cap_set_flag(d, CAP_EFFECTIVE, j, bits, CAP_SET) < 0 ||
-                    cap_set_flag(d, CAP_PERMITTED, j, bits, CAP_SET) < 0) {
-                        log_error_errno(errno, "Failed to enable capabilities bits: %m");
-                        return -errno;
-                }
+        if (cap_set_flag(d, CAP_EFFECTIVE, j, bits, CAP_SET) < 0 ||
+            cap_set_flag(d, CAP_PERMITTED, j, bits, CAP_SET) < 0) {
+                log_error_errno(errno, "Failed to enable capabilities bits: %m");
+                return -errno;
         }
 
         if (cap_set_proc(d) < 0)

commit 9e8abdf0d9f0fa11fbceb02dfd36252bd32a534e
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jan 29 02:10:15 2015 +0100

    Revert "journal: do not check for number of files"
    
    This reverts commit b914ea8d379b446c4c9fac4ba181771676ef38cd.
    
    We really need to put a limit on all our resources, everywhere, and in
    particular if we operate on external data.
    
    Hence, let's reintroduce the limit, but bump it substantially, so that
    it is guaranteed to be higher than any realistic RLIMIT_NOFILE setting.

diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index 0268675..9bc426f 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -43,6 +43,8 @@
 #include "replace-var.h"
 #include "fileio.h"
 
+#define JOURNAL_FILES_MAX 7168
+
 #define JOURNAL_FILES_RECHECK_USEC (2 * USEC_PER_SEC)
 
 #define REPLACE_VAR_MAX 256
@@ -1196,6 +1198,11 @@ static int add_any_file(sd_journal *j, const char *path) {
         if (ordered_hashmap_get(j->files, path))
                 return 0;
 
+        if (ordered_hashmap_size(j->files) >= JOURNAL_FILES_MAX) {
+                log_warning("Too many open journal files, not adding %s.", path);
+                return set_put_error(j, -ETOOMANYREFS);
+        }
+
         r = journal_file_open(path, O_RDONLY, 0, false, false, NULL, j->mmap, NULL, &f);
         if (r < 0)
                 return r;



More information about the systemd-commits mailing list