Pablo Greco 48fc63
From dec34b2c3b66f9ccf3977e3a45d3a8365ba92027 Mon Sep 17 00:00:00 2001
Pablo Greco 48fc63
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Pablo Greco 48fc63
Date: Thu, 3 Jan 2019 16:28:30 +0100
Pablo Greco 48fc63
Subject: [PATCH] journal-remote: set a limit on the number of fields in a
Pablo Greco 48fc63
 message
Pablo Greco 48fc63
Pablo Greco 48fc63
Existing use of E2BIG is replaced with ENOBUFS (entry too long), and E2BIG is
Pablo Greco 48fc63
reused for the new error condition (too many fields).
Pablo Greco 48fc63
Pablo Greco 48fc63
This matches the change done for systemd-journald, hence forming the second
Pablo Greco 48fc63
part of the fix for CVE-2018-16865
Pablo Greco 48fc63
(https://bugzilla.redhat.com/show_bug.cgi?id=1653861).
Pablo Greco 48fc63
Pablo Greco 48fc63
Resolves: #1657792
Pablo Greco 48fc63
---
Pablo Greco 48fc63
 src/journal-remote/journal-remote-parse.c |  2 +-
Pablo Greco 48fc63
 src/journal-remote/journal-remote-write.c |  3 +++
Pablo Greco 48fc63
 src/journal-remote/journal-remote.c       | 14 ++++++++++++--
Pablo Greco 48fc63
 3 files changed, 16 insertions(+), 3 deletions(-)
Pablo Greco 48fc63
Pablo Greco 48fc63
diff --git a/src/journal-remote/journal-remote-parse.c b/src/journal-remote/journal-remote-parse.c
Pablo Greco 48fc63
index 64089da19b..53f4e36123 100644
Pablo Greco 48fc63
--- a/src/journal-remote/journal-remote-parse.c
Pablo Greco 48fc63
+++ b/src/journal-remote/journal-remote-parse.c
Pablo Greco 48fc63
@@ -107,7 +107,7 @@ static int get_line(RemoteSource *source, char **line, size_t *size) {
Pablo Greco 48fc63
                 source->scanned = source->filled;
Pablo Greco 48fc63
                 if (source->scanned >= DATA_SIZE_MAX) {
Pablo Greco 48fc63
                         log_error("Entry is bigger than %u bytes.", DATA_SIZE_MAX);
Pablo Greco 48fc63
-                        return -E2BIG;
Pablo Greco 48fc63
+                        return -ENOBUFS;
Pablo Greco 48fc63
                 }
Pablo Greco 48fc63
 
Pablo Greco 48fc63
                 if (source->passive_fd)
Pablo Greco 48fc63
diff --git a/src/journal-remote/journal-remote-write.c b/src/journal-remote/journal-remote-write.c
Pablo Greco 48fc63
index 99820fa7b8..99920e62c5 100644
Pablo Greco 48fc63
--- a/src/journal-remote/journal-remote-write.c
Pablo Greco 48fc63
+++ b/src/journal-remote/journal-remote-write.c
Pablo Greco 48fc63
@@ -22,6 +22,9 @@
Pablo Greco 48fc63
 #include "journal-remote.h"
Pablo Greco 48fc63
 
Pablo Greco 48fc63
 int iovw_put(struct iovec_wrapper *iovw, void* data, size_t len) {
Pablo Greco 48fc63
+        if (iovw->count >= ENTRY_FIELD_COUNT_MAX)
Pablo Greco 48fc63
+                return -E2BIG;
Pablo Greco 48fc63
+
Pablo Greco 48fc63
         if (!GREEDY_REALLOC(iovw->iovec, iovw->size_bytes, iovw->count + 1))
Pablo Greco 48fc63
                 return log_oom();
Pablo Greco 48fc63
 
Pablo Greco 48fc63
diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c
Pablo Greco 48fc63
index a455fb6bd8..e65daf6a0b 100644
Pablo Greco 48fc63
--- a/src/journal-remote/journal-remote.c
Pablo Greco 48fc63
+++ b/src/journal-remote/journal-remote.c
Pablo Greco 48fc63
@@ -524,11 +524,18 @@ static int process_http_upload(
Pablo Greco 48fc63
                         break;
Pablo Greco 48fc63
                 else if (r < 0) {
Pablo Greco 48fc63
                         log_warning("Failed to process data for connection %p", connection);
Pablo Greco 48fc63
-                        if (r == -E2BIG)
Pablo Greco 48fc63
+                        if (r == -ENOBUFS)
Pablo Greco 48fc63
                                 return mhd_respondf(connection,
Pablo Greco 48fc63
                                                     MHD_HTTP_REQUEST_ENTITY_TOO_LARGE,
Pablo Greco 48fc63
                                                     "Entry is too large, maximum is %u bytes.\n",
Pablo Greco 48fc63
                                                     DATA_SIZE_MAX);
Pablo Greco 48fc63
+
Pablo Greco 48fc63
+                        else if (r == -E2BIG)
Pablo Greco 48fc63
+                                return mhd_respondf(connection,
Pablo Greco 48fc63
+                                                    MHD_HTTP_REQUEST_ENTITY_TOO_LARGE,
Pablo Greco 48fc63
+                                                    "Entry with more fields than the maximum of %u\n",
Pablo Greco 48fc63
+                                                    ENTRY_FIELD_COUNT_MAX);
Pablo Greco 48fc63
+
Pablo Greco 48fc63
                         else
Pablo Greco 48fc63
                                 return mhd_respondf(connection,
Pablo Greco 48fc63
                                                     MHD_HTTP_UNPROCESSABLE_ENTITY,
Pablo Greco 48fc63
@@ -1043,7 +1050,10 @@ static int handle_raw_source(sd_event_source *event,
Pablo Greco 48fc63
                 log_debug("%zu active sources remaining", s->active);
Pablo Greco 48fc63
                 return 0;
Pablo Greco 48fc63
         } else if (r == -E2BIG) {
Pablo Greco 48fc63
-                log_notice_errno(E2BIG, "Entry too big, skipped");
Pablo Greco 48fc63
+                log_notice_errno(E2BIG, "Entry with too many fields, skipped");
Pablo Greco 48fc63
+                return 1;
Pablo Greco 48fc63
+        } else if (r == -ENOBUFS) {
Pablo Greco 48fc63
+                log_notice_errno(ENOBUFS, "Entry too big, skipped");
Pablo Greco 48fc63
                 return 1;
Pablo Greco 48fc63
         } else if (r == -EAGAIN) {
Pablo Greco 48fc63
                 return 0;