diff --git a/1001-unit-name-generate-a-clear-error-code-when-convertin.patch b/1001-unit-name-generate-a-clear-error-code-when-convertin.patch new file mode 100644 index 00000000..3a090213 --- /dev/null +++ b/1001-unit-name-generate-a-clear-error-code-when-convertin.patch @@ -0,0 +1,63 @@ +From 83f392a392067d61be24eb720ff0cf1da7f1892b Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 1 Jun 2021 19:43:55 +0200 +Subject: [PATCH 1001/1003] unit-name: generate a clear error code when + converting an overly long fs path to a unit name + +(cherry picked from commit 9d5acfab20c5f1177d877d0bec18063c0a6c5929) + +[fbui: adjust context] +--- + src/basic/unit-name.c | 6 ++++++ + src/test/test-unit-name.c | 4 ++-- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c +index 532f8fa048..85dcba6cb7 100644 +--- a/src/basic/unit-name.c ++++ b/src/basic/unit-name.c +@@ -528,6 +528,9 @@ int unit_name_from_path(const char *path, const char *suffix, char **ret) { + if (!s) + return -ENOMEM; + ++ if (strlen(s) >= UNIT_NAME_MAX) /* Return a slightly more descriptive error for this specific condition */ ++ return -ENAMETOOLONG; ++ + /* Refuse this if this got too long or for some other reason didn't result in a valid name */ + if (!unit_name_is_valid(s, UNIT_NAME_PLAIN)) + return -EINVAL; +@@ -559,6 +562,9 @@ int unit_name_from_path_instance(const char *prefix, const char *path, const cha + if (!s) + return -ENOMEM; + ++ if (strlen(s) >= UNIT_NAME_MAX) /* Return a slightly more descriptive error for this specific condition */ ++ return -ENAMETOOLONG; ++ + /* Refuse this if this got too long or for some other reason didn't result in a valid name */ + if (!unit_name_is_valid(s, UNIT_NAME_INSTANCE)) + return -EINVAL; +diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c +index ece78aa548..c0b79715e1 100644 +--- a/src/test/test-unit-name.c ++++ b/src/test/test-unit-name.c +@@ -130,7 +130,7 @@ static void test_unit_name_from_path(void) { + test_unit_name_from_path_one("///", ".mount", "-.mount", 0); + test_unit_name_from_path_one("/foo/../bar", ".mount", NULL, -EINVAL); + test_unit_name_from_path_one("/foo/./bar", ".mount", NULL, -EINVAL); +- test_unit_name_from_path_one("/waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", ".mount", NULL, -EINVAL); ++ test_unit_name_from_path_one("/waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", ".mount", NULL, -ENAMETOOLONG); + } + + static void test_unit_name_from_path_instance_one(const char *pattern, const char *path, const char *suffix, const char *expected, int ret) { +@@ -160,7 +160,7 @@ static void test_unit_name_from_path_instance(void) { + test_unit_name_from_path_instance_one("waldo", "..", ".mount", NULL, -EINVAL); + test_unit_name_from_path_instance_one("waldo", "/foo", ".waldi", NULL, -EINVAL); + test_unit_name_from_path_instance_one("wa--ldo", "/--", ".mount", "wa--ldo@\\x2d\\x2d.mount", 0); +- test_unit_name_from_path_instance_one("waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "/waldo", ".mount", NULL, -EINVAL); ++ test_unit_name_from_path_instance_one("waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "/waldo", ".mount", NULL, -ENAMETOOLONG); + } + + static void test_unit_name_to_path_one(const char *unit, const char *path, int ret) { +-- +2.26.2 + diff --git a/1002-basic-unit-name-do-not-use-strdupa-on-a-path.patch b/1002-basic-unit-name-do-not-use-strdupa-on-a-path.patch new file mode 100644 index 00000000..a6f54db8 --- /dev/null +++ b/1002-basic-unit-name-do-not-use-strdupa-on-a-path.patch @@ -0,0 +1,67 @@ +From f636948448bd8a3588388d21dad737a079266392 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 23 Jun 2021 11:46:41 +0200 +Subject: [PATCH 1002/1003] basic/unit-name: do not use strdupa() on a path + +The path may have unbounded length, for example through a fuse mount. + +CVE-2021-33910: attacked controlled alloca() leads to crash in systemd and +ultimately a kernel panic. Systemd parses the content of /proc/self/mountinfo +and each mountpoint is passed to mount_setup_unit(), which calls +unit_name_path_escape() underneath. A local attacker who is able to mount a +filesystem with a very long path can crash systemd and the whole system. + +https://bugzilla.redhat.com/show_bug.cgi?id=1970887 + +The resulting string length is bounded by UNIT_NAME_MAX, which is 256. But we +can't easily check the length after simplification before doing the +simplification, which in turns uses a copy of the string we can write to. +So we can't reject paths that are too long before doing the duplication. +Hence the most obvious solution is to switch back to strdup(), as before +7410616cd9dbbec97cf98d75324da5cda2b2f7a2. + +[fbui: fixes bsc#1188063] +[fbui: fixes CVE-2021-33910] +--- + src/basic/unit-name.c | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c +index 85dcba6cb7..46b24f2d9e 100644 +--- a/src/basic/unit-name.c ++++ b/src/basic/unit-name.c +@@ -378,12 +378,13 @@ int unit_name_unescape(const char *f, char **ret) { + } + + int unit_name_path_escape(const char *f, char **ret) { +- char *p, *s; ++ _cleanup_free_ char *p = NULL; ++ char *s; + + assert(f); + assert(ret); + +- p = strdupa(f); ++ p = strdup(f); + if (!p) + return -ENOMEM; + +@@ -395,13 +396,9 @@ int unit_name_path_escape(const char *f, char **ret) { + if (!path_is_normalized(p)) + return -EINVAL; + +- /* Truncate trailing slashes */ ++ /* Truncate trailing slashes and skip leading slashes */ + delete_trailing_chars(p, "/"); +- +- /* Truncate leading slashes */ +- p = skip_leading_chars(p, "/"); +- +- s = unit_name_escape(p); ++ s = unit_name_escape(skip_leading_chars(p, "/")); + } + if (!s) + return -ENOMEM; +-- +2.26.2 + diff --git a/1003-basic-unit-name-adjust-comments.patch b/1003-basic-unit-name-adjust-comments.patch new file mode 100644 index 00000000..98cad8b5 --- /dev/null +++ b/1003-basic-unit-name-adjust-comments.patch @@ -0,0 +1,38 @@ +From 9731d5204357d43204ca83155f5b552594b843bc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 23 Jun 2021 11:52:56 +0200 +Subject: [PATCH 1003/1003] basic/unit-name: adjust comments +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We already checked for "too long" right aboveā€¦ +--- + src/basic/unit-name.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c +index 46b24f2d9e..c5850949ae 100644 +--- a/src/basic/unit-name.c ++++ b/src/basic/unit-name.c +@@ -528,7 +528,7 @@ int unit_name_from_path(const char *path, const char *suffix, char **ret) { + if (strlen(s) >= UNIT_NAME_MAX) /* Return a slightly more descriptive error for this specific condition */ + return -ENAMETOOLONG; + +- /* Refuse this if this got too long or for some other reason didn't result in a valid name */ ++ /* Refuse if this for some other reason didn't result in a valid name */ + if (!unit_name_is_valid(s, UNIT_NAME_PLAIN)) + return -EINVAL; + +@@ -562,7 +562,7 @@ int unit_name_from_path_instance(const char *prefix, const char *path, const cha + if (strlen(s) >= UNIT_NAME_MAX) /* Return a slightly more descriptive error for this specific condition */ + return -ENAMETOOLONG; + +- /* Refuse this if this got too long or for some other reason didn't result in a valid name */ ++ /* Refuse if this for some other reason didn't result in a valid name */ + if (!unit_name_is_valid(s, UNIT_NAME_INSTANCE)) + return -EINVAL; + +-- +2.26.2 + diff --git a/systemd-mini.changes b/systemd-mini.changes index 56a68bbe..84cd5d49 100644 --- a/systemd-mini.changes +++ b/systemd-mini.changes @@ -1,3 +1,15 @@ +------------------------------------------------------------------- +Thu Jul 8 18:04:31 UTC 2021 - Franck Bui + +- Added patches to fix CVE-2021-33910 (bsc#1188063) + + Added 1001-unit-name-generate-a-clear-error-code-when-convertin.patch + Added 1002-basic-unit-name-do-not-use-strdupa-on-a-path.patch + Added 1003-basic-unit-name-adjust-comments.patch + + These patches will be moved to the git repo once the bug will become + public. + ------------------------------------------------------------------- Mon Jul 5 09:03:07 UTC 2021 - Franck Bui diff --git a/systemd-mini.spec b/systemd-mini.spec index 6ac270de..50b3bf24 100644 --- a/systemd-mini.spec +++ b/systemd-mini.spec @@ -197,6 +197,12 @@ Patch12: 0012-resolved-create-etc-resolv.conf-symlink-at-runtime.patch # upstream. Patch100: 0001-Revert-core-prevent-excessive-proc-self-mountinfo-pa.patch +# Patches for bsc#1188063/CVE-2021-33910. They will be moved to the +# git repo once the bug will become public. +Patch1001: 1001-unit-name-generate-a-clear-error-code-when-convertin.patch +Patch1002: 1002-basic-unit-name-do-not-use-strdupa-on-a-path.patch +Patch1003: 1003-basic-unit-name-adjust-comments.patch + %description Systemd is a system and service manager, compatible with SysV and LSB init scripts for Linux. systemd provides aggressive parallelization diff --git a/systemd.changes b/systemd.changes index 56a68bbe..84cd5d49 100644 --- a/systemd.changes +++ b/systemd.changes @@ -1,3 +1,15 @@ +------------------------------------------------------------------- +Thu Jul 8 18:04:31 UTC 2021 - Franck Bui + +- Added patches to fix CVE-2021-33910 (bsc#1188063) + + Added 1001-unit-name-generate-a-clear-error-code-when-convertin.patch + Added 1002-basic-unit-name-do-not-use-strdupa-on-a-path.patch + Added 1003-basic-unit-name-adjust-comments.patch + + These patches will be moved to the git repo once the bug will become + public. + ------------------------------------------------------------------- Mon Jul 5 09:03:07 UTC 2021 - Franck Bui diff --git a/systemd.spec b/systemd.spec index c7f61a2c..dd5ca994 100644 --- a/systemd.spec +++ b/systemd.spec @@ -195,6 +195,12 @@ Patch12: 0012-resolved-create-etc-resolv.conf-symlink-at-runtime.patch # upstream. Patch100: 0001-Revert-core-prevent-excessive-proc-self-mountinfo-pa.patch +# Patches for bsc#1188063/CVE-2021-33910. They will be moved to the +# git repo once the bug will become public. +Patch1001: 1001-unit-name-generate-a-clear-error-code-when-convertin.patch +Patch1002: 1002-basic-unit-name-do-not-use-strdupa-on-a-path.patch +Patch1003: 1003-basic-unit-name-adjust-comments.patch + %description Systemd is a system and service manager, compatible with SysV and LSB init scripts for Linux. systemd provides aggressive parallelization