chiark / gitweb /
journal: allow callers to specify OBJECT_PID=
[elogind.git] / src / journal / journald-native.c
index 069114778b39926159f1e522fb377d4abe27a08d..0f9af378cfd072dc7f8f87498cf920674c13e12d 100644 (file)
 #include "journald-console.h"
 #include "journald-syslog.h"
 
-#define ENTRY_SIZE_MAX (1024*1024*64)
-#define DATA_SIZE_MAX (1024*1024*64)
+/* Make sure not to make this smaller than the maximum coredump
+ * size. See COREDUMP_MAX in coredump.c */
+#define ENTRY_SIZE_MAX (1024*1024*768)
+#define DATA_SIZE_MAX (1024*1024*768)
 
 static bool valid_user_field(const char *p, size_t l) {
         const char *a;
@@ -69,6 +71,10 @@ static bool valid_user_field(const char *p, size_t l) {
         return true;
 }
 
+static bool allow_object_pid(struct ucred *ucred) {
+        return ucred && ucred->uid == 0;
+}
+
 void server_process_native_message(
                 Server *s,
                 const void *buffer, size_t buffer_size,
@@ -77,11 +83,12 @@ void server_process_native_message(
                 const char *label, size_t label_len) {
 
         struct iovec *iovec = NULL;
-        unsigned n = 0, m = 0, j, tn = (unsigned) -1;
+        unsigned n = 0, j, tn = (unsigned) -1;
         const char *p;
-        size_t remaining;
+        size_t remaining, m = 0;
         int priority = LOG_INFO;
         char *identifier = NULL, *message = NULL;
+        pid_t object_pid = 0;
 
         assert(s);
         assert(buffer || buffer_size == 0);
@@ -102,7 +109,7 @@ void server_process_native_message(
 
                 if (e == p) {
                         /* Entry separator */
-                        server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority);
+                        server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority, object_pid);
                         n = 0;
                         priority = LOG_INFO;
 
@@ -121,19 +128,11 @@ void server_process_native_message(
 
                 /* A property follows */
 
-                if (n+N_IOVEC_META_FIELDS >= m) {
-                        struct iovec *c;
-                        unsigned u;
-
-                        u = MAX((n+N_IOVEC_META_FIELDS+1) * 2U, 4U);
-                        c = realloc(iovec, u * sizeof(struct iovec));
-                        if (!c) {
-                                log_oom();
-                                break;
-                        }
-
-                        iovec = c;
-                        m = u;
+                /* n received properties, +1 for _TRANSPORT */
+                if (!GREEDY_REALLOC(iovec, m, n + 1 + N_IOVEC_META_FIELDS +
+                                              !!object_pid * N_IOVEC_OBJECT_FIELDS)) {
+                        log_oom();
+                        break;
                 }
 
                 q = memchr(p, '=', e - p);
@@ -155,23 +154,23 @@ void server_process_native_message(
                                  * of this entry for the rate limiting
                                  * logic */
                                 if (l == 10 &&
-                                    memcmp(p, "PRIORITY=", 9) == 0 &&
+                                    hasprefix(p, "PRIORITY=") &&
                                     p[9] >= '0' && p[9] <= '9')
                                         priority = (priority & LOG_FACMASK) | (p[9] - '0');
 
                                 else if (l == 17 &&
-                                         memcmp(p, "SYSLOG_FACILITY=", 16) == 0 &&
+                                         hasprefix(p, "SYSLOG_FACILITY=") &&
                                          p[16] >= '0' && p[16] <= '9')
                                         priority = (priority & LOG_PRIMASK) | ((p[16] - '0') << 3);
 
                                 else if (l == 18 &&
-                                         memcmp(p, "SYSLOG_FACILITY=", 16) == 0 &&
+                                         hasprefix(p, "SYSLOG_FACILITY=") &&
                                          p[16] >= '0' && p[16] <= '9' &&
                                          p[17] >= '0' && p[17] <= '9')
                                         priority = (priority & LOG_PRIMASK) | (((p[16] - '0')*10 + (p[17] - '0')) << 3);
 
                                 else if (l >= 19 &&
-                                         memcmp(p, "SYSLOG_IDENTIFIER=", 18) == 0) {
+                                         hasprefix(p, "SYSLOG_IDENTIFIER=")) {
                                         char *t;
 
                                         t = strndup(p + 18, l - 18);
@@ -180,7 +179,7 @@ void server_process_native_message(
                                                 identifier = t;
                                         }
                                 } else if (l >= 8 &&
-                                           memcmp(p, "MESSAGE=", 8) == 0) {
+                                           hasprefix(p, "MESSAGE=")) {
                                         char *t;
 
                                         t = strndup(p + 8, l - 8);
@@ -188,6 +187,16 @@ void server_process_native_message(
                                                 free(message);
                                                 message = t;
                                         }
+                                } else if (l > strlen("OBJECT_PID=") &&
+                                           l < strlen("OBJECT_PID=")  + DECIMAL_STR_MAX(pid_t) &&
+                                           hasprefix(p, "OBJECT_PID=") &&
+                                           allow_object_pid(ucred)) {
+                                        char buf[DECIMAL_STR_MAX(pid_t)];
+                                        memcpy(buf, p + strlen("OBJECT_PID="), l - strlen("OBJECT_PID="));
+                                        char_array_0(buf);
+
+                                        /* ignore error */
+                                        parse_pid(buf, &object_pid);
                                 }
                         }
 
@@ -257,7 +266,7 @@ void server_process_native_message(
                         server_forward_console(s, priority, identifier, message, ucred);
         }
 
-        server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority);
+        server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority, object_pid);
 
 finish:
         for (j = 0; j < n; j++)  {