systemd: Update recent CVE patches

* Added CVE tag, Upstream-Status tag and Sign-off-by tags.
* Removed the verification of the entry length in the header
* Squashed CVE-2018-16865 patches into one
* CVE-2018-16866 patch now taken from systemd-stable and includes
  an additional heap buffer overflow fix.

(From OE-Core rev: bc79395e2fcb886f224a4ad837fd93c779d2c53d)

Signed-off-by: Marcus Cooper <marcusc@axis.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Richard Purdie
2019-01-28 13:57:44 +00:00
parent 64e39849c5
commit af0b3d6909
8 changed files with 195 additions and 306 deletions

View File

@@ -1,4 +1,4 @@
From fe19f5a9d0d8b9977e9507a9b66c3cc66744cd38 Mon Sep 17 00:00:00 2001
From 9cb07e7d82c7c4f28bbaa1478e1387e8ea3d03dd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Wed, 5 Dec 2018 18:38:39 +0100
Subject: [PATCH] journald: do not store the iovec entry for process
@@ -16,6 +16,10 @@ journal_file_append_entry() returns -E2BIG.
Patch backported from systemd master at
084eeb865ca63887098e0945fb4e93c852b91b0f.
CVE: CVE-2018-16864
Upstream-Status: Backport
Signed-off-by: Marcus Cooper <marcusc@axis.com>
---
src/basic/io-util.c | 10 ++++++++++
src/basic/io-util.h | 2 ++

View File

@@ -1,56 +0,0 @@
From 4566aaf97f5b4143b930d75628f3abc905249dcd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Wed, 5 Dec 2018 22:45:02 +0100
Subject: [PATCH] journald: set a limit on the number of fields (1k)
We allocate a iovec entry for each field, so with many short entries,
our memory usage and processing time can be large, even with a relatively
small message size. Let's refuse overly long entries.
CVE-2018-16865
https://bugzilla.redhat.com/show_bug.cgi?id=1653861
What from I can see, the problem is not from an alloca, despite what the CVE
description says, but from the attack multiplication that comes from creating
many very small iovecs: (void* + size_t) for each three bytes of input message.
Patch backported from systemd master at
052c57f132f04a3cf4148f87561618da1a6908b4.
---
src/basic/journal-importer.h | 3 +++
src/journal/journald-native.c | 5 +++++
2 files changed, 8 insertions(+)
diff --git a/src/basic/journal-importer.h b/src/basic/journal-importer.h
index f49ce734a1..c4ae45d32d 100644
--- a/src/basic/journal-importer.h
+++ b/src/basic/journal-importer.h
@@ -16,6 +16,9 @@
#define DATA_SIZE_MAX (1024*1024*768u)
#define LINE_CHUNK 8*1024u
+/* The maximum number of fields in an entry */
+#define ENTRY_FIELD_COUNT_MAX 1024
+
struct iovec_wrapper {
struct iovec *iovec;
size_t size_bytes;
diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c
index 5ff22a10af..951d092053 100644
--- a/src/journal/journald-native.c
+++ b/src/journal/journald-native.c
@@ -140,6 +140,11 @@ static int server_process_entry(
}
/* A property follows */
+ if (n > ENTRY_FIELD_COUNT_MAX) {
+ log_debug("Received an entry that has more than " STRINGIFY(ENTRY_FIELD_COUNT_MAX) " fields, ignoring entry.");
+ r = 1;
+ goto finish;
+ }
/* n existing properties, 1 new, +1 for _TRANSPORT */
if (!GREEDY_REALLOC(iovec, m,
--
2.11.0

View File

@@ -0,0 +1,139 @@
From 7cad044b72406cbadf048da432c29afea74c3c10 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Wed, 5 Dec 2018 22:45:02 +0100
Subject: [PATCH] journald: set a limit on the number of fields
The fix for CVE-2018-16865 is plucked from two commits that have
been pushed to systemd master.
journald: set a limit on the number of fields (1k)
We allocate a iovec entry for each field, so with many short entries,
our memory usage and processing time can be large, even with a relatively
small message size. Let's refuse overly long entries.
CVE-2018-16865
https://bugzilla.redhat.com/show_bug.cgi?id=1653861
What from I can see, the problem is not from an alloca, despite what the CVE
description says, but from the attack multiplication that comes from creating
many very small iovecs: (void* + size_t) for each three bytes of input message.
Patch backported from systemd master at
052c57f132f04a3cf4148f87561618da1a6908b4.
journal-remote: set a limit on the number of fields in a message
Existing use of E2BIG is replaced with ENOBUFS (entry too long), and E2BIG is
reused for the new error condition (too many fields).
This matches the change done for systemd-journald, hence forming the second
part of the fix for CVE-2018-16865
(https://bugzilla.redhat.com/show_bug.cgi?id=1653861).
Patch backported from systemd master at
ef4d6abe7c7fab6cbff975b32e76b09feee56074.
with the changes applied by 7fdb237f5473cb8fc2129e57e8a0039526dcb4fd
removed.
CVE: CVE-2018-16865
Upstream-Status: Backport
Signed-off-by: Marcus Cooper <marcusc@axis.com>
---
src/basic/journal-importer.c | 5 ++++-
src/basic/journal-importer.h | 3 +++
src/journal-remote/journal-remote-main.c | 7 ++++++-
src/journal-remote/journal-remote.c | 5 ++++-
src/journal/journald-native.c | 5 +++++
5 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/src/basic/journal-importer.c b/src/basic/journal-importer.c
index ca203bbbfc..3ac55a66d9 100644
--- a/src/basic/journal-importer.c
+++ b/src/basic/journal-importer.c
@@ -23,6 +23,9 @@ enum {
};
static int iovw_put(struct iovec_wrapper *iovw, void* data, size_t len) {
+ if (iovw->count >= ENTRY_FIELD_COUNT_MAX)
+ return -E2BIG;
+
if (!GREEDY_REALLOC(iovw->iovec, iovw->size_bytes, iovw->count + 1))
return log_oom();
@@ -98,7 +101,7 @@ static int get_line(JournalImporter *imp, char **line, size_t *size) {
imp->scanned = imp->filled;
if (imp->scanned >= DATA_SIZE_MAX) {
log_error("Entry is bigger than %u bytes.", DATA_SIZE_MAX);
- return -E2BIG;
+ return -ENOBUFS;
}
if (imp->passive_fd)
diff --git a/src/basic/journal-importer.h b/src/basic/journal-importer.h
index f49ce734a1..c4ae45d32d 100644
--- a/src/basic/journal-importer.h
+++ b/src/basic/journal-importer.h
@@ -16,6 +16,9 @@
#define DATA_SIZE_MAX (1024*1024*768u)
#define LINE_CHUNK 8*1024u
+/* The maximum number of fields in an entry */
+#define ENTRY_FIELD_COUNT_MAX 1024
+
struct iovec_wrapper {
struct iovec *iovec;
size_t size_bytes;
diff --git a/src/journal-remote/journal-remote-main.c b/src/journal-remote/journal-remote-main.c
index 8fda9d1499..3a01fef646 100644
--- a/src/journal-remote/journal-remote-main.c
+++ b/src/journal-remote/journal-remote-main.c
@@ -212,7 +212,12 @@ static int process_http_upload(
break;
else if (r < 0) {
log_warning("Failed to process data for connection %p", connection);
- if (r == -E2BIG)
+ if (r == -ENOBUFS)
+ return mhd_respondf(connection,
+ r, MHD_HTTP_PAYLOAD_TOO_LARGE,
+ "Entry is above the maximum of %u, aborting connection %p.",
+ DATA_SIZE_MAX, connection);
+ else if (r == -E2BIG)
return mhd_respondf(connection,
r, MHD_HTTP_PAYLOAD_TOO_LARGE,
"Entry is too large, maximum is " STRINGIFY(DATA_SIZE_MAX) " bytes.");
diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c
index beb75a1cb4..67e3a70c06 100644
--- a/src/journal-remote/journal-remote.c
+++ b/src/journal-remote/journal-remote.c
@@ -408,7 +408,10 @@ int journal_remote_handle_raw_source(
log_debug("%zu active sources remaining", s->active);
return 0;
} else if (r == -E2BIG) {
- log_notice_errno(E2BIG, "Entry too big, skipped");
+ log_notice("Entry with too many fields, skipped");
+ return 1;
+ } else if (r == -ENOBUFS) {
+ log_notice("Entry too big, skipped");
return 1;
} else if (r == -EAGAIN) {
return 0;
diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c
index 5ff22a10af..951d092053 100644
--- a/src/journal/journald-native.c
+++ b/src/journal/journald-native.c
@@ -140,6 +140,11 @@ static int server_process_entry(
}
/* A property follows */
+ if (n > ENTRY_FIELD_COUNT_MAX) {
+ log_debug("Received an entry that has more than " STRINGIFY(ENTRY_FIELD_COUNT_MAX) " fields, ignoring entry.");
+ r = 1;
+ goto finish;
+ }
/* n existing properties, 1 new, +1 for _TRANSPORT */
if (!GREEDY_REALLOC(iovec, m,
--
2.11.0

View File

@@ -0,0 +1,49 @@
From ebd06c37d4311db9851f4d3fdd023de3dd590de0 Mon Sep 17 00:00:00 2001
From: Filipe Brandenburger <filbranden@google.com>
Date: Thu, 10 Jan 2019 14:53:33 -0800
Subject: [PATCH] journal: fix out-of-bounds read CVE-2018-16866
The original code didn't account for the fact that strchr() would match on the
'\0' character, making it read past the end of the buffer if no non-whitespace
character was present.
This bug was introduced in commit ec5ff4445cca6a which was first released in
systemd v221 and later fixed in commit 8595102d3ddde6 which was released in
v240, so versions in the range [v221, v240) are affected.
Patch backported from systemd-stable at f005e73d3723d62a39be661931fcb6347119b52b
also includes a change from systemd master which removes a heap buffer overflow
a6aadf4ae0bae185dc4c414d492a4a781c80ffe5.
CVE: CVE-2018-16866
Upstream-Status: Backport
Signed-off-by: Marcus Cooper <marcusc@axis.com>
---
src/journal/journald-syslog.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c
index 9dea116722..809b318c06 100644
--- a/src/journal/journald-syslog.c
+++ b/src/journal/journald-syslog.c
@@ -194,7 +194,7 @@ size_t syslog_parse_identifier(const char **buf, char **identifier, char **pid)
e = l;
l--;
- if (p[l-1] == ']') {
+ if (l > 0 && p[l-1] == ']') {
size_t k = l-1;
for (;;) {
@@ -219,7 +219,7 @@ size_t syslog_parse_identifier(const char **buf, char **identifier, char **pid)
if (t)
*identifier = t;
- if (strchr(WHITESPACE, p[e]))
+ if (p[e] != '\0' && strchr(WHITESPACE, p[e]))
e++;
*buf = p + e;
return e;
--
2.11.0

View File

@@ -1,84 +0,0 @@
From 4183ec3a135663128834ca8b35d50a60999343a7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Fri, 7 Dec 2018 10:48:10 +0100
Subject: [PATCH] journal-remote: set a limit on the number of fields in a
message
Existing use of E2BIG is replaced with ENOBUFS (entry too long), and E2BIG is
reused for the new error condition (too many fields).
This matches the change done for systemd-journald, hence forming the second
part of the fix for CVE-2018-16865
(https://bugzilla.redhat.com/show_bug.cgi?id=1653861).
Patch backported from systemd master at
ef4d6abe7c7fab6cbff975b32e76b09feee56074.
---
src/basic/journal-importer.c | 5 ++++-
src/journal-remote/journal-remote-main.c | 10 ++++++----
src/journal-remote/journal-remote.c | 5 ++++-
3 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/src/basic/journal-importer.c b/src/basic/journal-importer.c
index ca203bbbfc..3ac55a66d9 100644
--- a/src/basic/journal-importer.c
+++ b/src/basic/journal-importer.c
@@ -23,6 +23,9 @@ enum {
};
static int iovw_put(struct iovec_wrapper *iovw, void* data, size_t len) {
+ if (iovw->count >= ENTRY_FIELD_COUNT_MAX)
+ return -E2BIG;
+
if (!GREEDY_REALLOC(iovw->iovec, iovw->size_bytes, iovw->count + 1))
return log_oom();
@@ -98,7 +101,7 @@ static int get_line(JournalImporter *imp, char **line, size_t *size) {
imp->scanned = imp->filled;
if (imp->scanned >= DATA_SIZE_MAX) {
log_error("Entry is bigger than %u bytes.", DATA_SIZE_MAX);
- return -E2BIG;
+ return -ENOBUFS;
}
if (imp->passive_fd)
diff --git a/src/journal-remote/journal-remote-main.c b/src/journal-remote/journal-remote-main.c
index 8fda9d1499..f52618fb7b 100644
--- a/src/journal-remote/journal-remote-main.c
+++ b/src/journal-remote/journal-remote-main.c
@@ -212,10 +212,12 @@ static int process_http_upload(
break;
else if (r < 0) {
log_warning("Failed to process data for connection %p", connection);
- if (r == -E2BIG)
- return mhd_respondf(connection,
- r, MHD_HTTP_PAYLOAD_TOO_LARGE,
- "Entry is too large, maximum is " STRINGIFY(DATA_SIZE_MAX) " bytes.");
+ if (r == -ENOBUFS)
+ log_warning_errno(r, "Entry is above the maximum of %u, aborting connection %p.",
+ DATA_SIZE_MAX, connection);
+ else if (r == -E2BIG)
+ log_warning_errno(r, "Entry with more fields than the maximum of %u, aborting connection %p.",
+ ENTRY_FIELD_COUNT_MAX, connection);
else
return mhd_respondf(connection,
r, MHD_HTTP_UNPROCESSABLE_ENTITY,
diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c
index beb75a1cb4..67e3a70c06 100644
--- a/src/journal-remote/journal-remote.c
+++ b/src/journal-remote/journal-remote.c
@@ -408,7 +408,10 @@ int journal_remote_handle_raw_source(
log_debug("%zu active sources remaining", s->active);
return 0;
} else if (r == -E2BIG) {
- log_notice_errno(E2BIG, "Entry too big, skipped");
+ log_notice("Entry with too many fields, skipped");
+ return 1;
+ } else if (r == -ENOBUFS) {
+ log_notice("Entry too big, skipped");
return 1;
} else if (r == -EAGAIN) {
return 0;
--
2.11.0

View File

@@ -1,77 +0,0 @@
From 8ccebb04e07628f7fe10131d6cd4f19d6a0d8f45 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 8 Aug 2018 15:06:36 +0900
Subject: [PATCH] journal: fix syslog_parse_identifier()
Fixes #9829.
An out of bounds read was discovered in systemd-journald in the way it
parses log messages that terminate with a colon ':'. A local attacker
can use this flaw to disclose process memory data.
Patch backported from systemd master at
a6aadf4ae0bae185dc4c414d492a4a781c80ffe5.
This matches the change done for systemd-journald, hence forming the first
part of the fix for CVE-2018-16866.
---
src/journal/journald-syslog.c | 6 +++---
src/journal/test-journal-syslog.c | 10 ++++++++--
2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c
index 9dea116722..97711ac7a3 100644
--- a/src/journal/journald-syslog.c
+++ b/src/journal/journald-syslog.c
@@ -194,7 +194,7 @@ size_t syslog_parse_identifier(const char **buf, char **identifier, char **pid)
e = l;
l--;
- if (p[l-1] == ']') {
+ if (l > 0 && p[l-1] == ']') {
size_t k = l-1;
for (;;) {
@@ -219,8 +219,8 @@ size_t syslog_parse_identifier(const char **buf, char **identifier, char **pid)
if (t)
*identifier = t;
- if (strchr(WHITESPACE, p[e]))
- e++;
+ e += strspn(p + e, WHITESPACE);
+
*buf = p + e;
return e;
}
diff --git a/src/journal/test-journal-syslog.c b/src/journal/test-journal-syslog.c
index 9ba86f6c8a..05f759817e 100644
--- a/src/journal/test-journal-syslog.c
+++ b/src/journal/test-journal-syslog.c
@@ -5,8 +5,8 @@
#include "macro.h"
#include "string-util.h"
-static void test_syslog_parse_identifier(const char* str,
- const char *ident, const char*pid, int ret) {
+static void test_syslog_parse_identifier(const char *str,
+ const char *ident, const char *pid, int ret) {
const char *buf = str;
_cleanup_free_ char *ident2 = NULL, *pid2 = NULL;
int ret2;
@@ -21,7 +21,13 @@ static void test_syslog_parse_identifier(const char* str,
int main(void) {
test_syslog_parse_identifier("pidu[111]: xxx", "pidu", "111", 11);
test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, 6);
+ test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, 7);
test_syslog_parse_identifier("pidu xxx", NULL, NULL, 0);
+ test_syslog_parse_identifier(":", "", NULL, 1);
+ test_syslog_parse_identifier(": ", "", NULL, 3);
+ test_syslog_parse_identifier("pidu:", "pidu", NULL, 5);
+ test_syslog_parse_identifier("pidu: ", "pidu", NULL, 6);
+ test_syslog_parse_identifier("pidu : ", NULL, NULL, 0);
return 0;
}
--
2.11.0

View File

@@ -1,84 +0,0 @@
From c3a7da1bbb6d2df8ab7ea1c7ce34ded37a21959f Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Fri, 10 Aug 2018 11:07:54 +0900
Subject: [PATCH] journal: do not remove multiple spaces after identifier in
syslog message
Single space is used as separator.
C.f. discussions in #156.
Fixes #9839 introduced by a6aadf4ae0bae185dc4c414d492a4a781c80ffe5.
Patch backported from systemd master at
8595102d3ddde6d25c282f965573a6de34ab4421.
This matches the change done for systemd-journald, hence forming the second
part of the fix for CVE-2018-16866
---
src/journal/journald-syslog.c | 4 +++-
src/journal/test-journal-syslog.c | 24 ++++++++++++++----------
2 files changed, 17 insertions(+), 11 deletions(-)
diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c
index 97711ac7a3..e0b55cc566 100644
--- a/src/journal/journald-syslog.c
+++ b/src/journal/journald-syslog.c
@@ -219,7 +219,9 @@ size_t syslog_parse_identifier(const char **buf, char **identifier, char **pid)
if (t)
*identifier = t;
- e += strspn(p + e, WHITESPACE);
+ /* Single space is used as separator */
+ if (p[e] != '\0' && strchr(WHITESPACE, p[e]))
+ e++;
*buf = p + e;
return e;
diff --git a/src/journal/test-journal-syslog.c b/src/journal/test-journal-syslog.c
index 05f759817e..7294cde032 100644
--- a/src/journal/test-journal-syslog.c
+++ b/src/journal/test-journal-syslog.c
@@ -6,7 +6,7 @@
#include "string-util.h"
static void test_syslog_parse_identifier(const char *str,
- const char *ident, const char *pid, int ret) {
+ const char *ident, const char *pid, const char *rest, int ret) {
const char *buf = str;
_cleanup_free_ char *ident2 = NULL, *pid2 = NULL;
int ret2;
@@ -16,18 +16,22 @@ static void test_syslog_parse_identifier(const char *str,
assert_se(ret == ret2);
assert_se(ident == ident2 || streq_ptr(ident, ident2));
assert_se(pid == pid2 || streq_ptr(pid, pid2));
+ assert_se(streq(buf, rest));
}
int main(void) {
- test_syslog_parse_identifier("pidu[111]: xxx", "pidu", "111", 11);
- test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, 6);
- test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, 7);
- test_syslog_parse_identifier("pidu xxx", NULL, NULL, 0);
- test_syslog_parse_identifier(":", "", NULL, 1);
- test_syslog_parse_identifier(": ", "", NULL, 3);
- test_syslog_parse_identifier("pidu:", "pidu", NULL, 5);
- test_syslog_parse_identifier("pidu: ", "pidu", NULL, 6);
- test_syslog_parse_identifier("pidu : ", NULL, NULL, 0);
+ test_syslog_parse_identifier("pidu[111]: xxx", "pidu", "111", "xxx", 11);
+ test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, "xxx", 6);
+ test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, " xxx", 6);
+ test_syslog_parse_identifier("pidu xxx", NULL, NULL, "pidu xxx", 0);
+ test_syslog_parse_identifier(" pidu xxx", NULL, NULL, " pidu xxx", 0);
+ test_syslog_parse_identifier("", NULL, NULL, "", 0);
+ test_syslog_parse_identifier(" ", NULL, NULL, " ", 0);
+ test_syslog_parse_identifier(":", "", NULL, "", 1);
+ test_syslog_parse_identifier(": ", "", NULL, " ", 2);
+ test_syslog_parse_identifier("pidu:", "pidu", NULL, "", 5);
+ test_syslog_parse_identifier("pidu: ", "pidu", NULL, "", 6);
+ test_syslog_parse_identifier("pidu : ", NULL, NULL, "pidu : ", 0);
return 0;
}
--
2.11.0

View File

@@ -39,10 +39,8 @@ SRC_URI += "file://touchscreen.rules \
file://0002-core-Fix-use-after-free-case-in-load_from_path.patch \
file://0001-meson-rename-Ddebug-to-Ddebug-extra.patch \
file://0024-journald-do-not-store-the-iovec-entry-for-process-co.patch \
file://0025-journald-set-a-limit-on-the-number-of-fields-1k.patch \
file://0026-journal-remote-set-a-limit-on-the-number-of-fields-i.patch \
file://0027-journal-fix-syslog_parse_identifier.patch \
file://0028-journal-do-not-remove-multiple-spaces-after-identifi.patch \
file://0025-journald-set-a-limit-on-the-number-of-fields.patch \
file://0026-journal-fix-out-of-bounds-read-CVE-2018-16866.patch \
"
# patches made for musl are only applied on TCLIBC is musl