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