NetworkManager/SOURCES/1005-initrd-fix-crash-parsi...

80 lines
3.3 KiB
Diff

From 31e882a46229c74649216ddc80fdb2ecbf75ab9e Mon Sep 17 00:00:00 2001
From: Beniamino Galvani <bgalvani@redhat.com>
Date: Tue, 16 Mar 2021 10:00:44 +0100
Subject: [PATCH 1/1] initrd: fix crash parsing empty rd.znet argument
Ignore a rd.znet argument without subchannels. When using net.ifnames
(the default), subchannels are used to build the interface name, which
is required to match the right connection.
With net.ifnames=0 the interface name is build using a prefix and a
global counter and therefore in theory it is possible to omit
subchannels. However, without subchannels there won't be a udev rule
that renames the interface and so it can't work.
https://bugzilla.redhat.com/show_bug.cgi?id=1931284
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/783
(cherry picked from commit 0f8fe3c76b9ecdf52c1690295f7dcc7b7ade16b6)
(cherry picked from commit d0d2d97ca51444bc7013943748ede334cc79a33f)
---
src/core/initrd/nmi-cmdline-reader.c | 5 +++++
src/core/initrd/tests/test-cmdline-reader.c | 19 +++++++++++++++++++
2 files changed, 24 insertions(+)
diff --git a/src/core/initrd/nmi-cmdline-reader.c b/src/core/initrd/nmi-cmdline-reader.c
index 5f40f63ef269..e3ecc7d969bb 100644
--- a/src/core/initrd/nmi-cmdline-reader.c
+++ b/src/core/initrd/nmi-cmdline-reader.c
@@ -917,6 +917,11 @@ reader_parse_rd_znet(Reader *reader, char *argument, gboolean net_ifnames)
subchannels[0] = get_word(&argument, ',');
subchannels[1] = get_word(&argument, ',');
+ /* Without subchannels we can't univocally match
+ * a device. */
+ if (!subchannels[0] || !subchannels[1])
+ return;
+
if (nm_streq0(nettype, "ctc")) {
if (net_ifnames == TRUE) {
prefix = "sl";
diff --git a/src/core/initrd/tests/test-cmdline-reader.c b/src/core/initrd/tests/test-cmdline-reader.c
index 4b450aae0fa4..ba072e7933dc 100644
--- a/src/core/initrd/tests/test-cmdline-reader.c
+++ b/src/core/initrd/tests/test-cmdline-reader.c
@@ -1815,6 +1815,24 @@ test_rd_znet_no_ip(void)
g_assert_cmpint(g_hash_table_size(connections), ==, 0);
}
+static void
+test_rd_znet_malformed(void)
+{
+ const char *const *const ARGV0 = NM_MAKE_STRV("rd.znet=");
+ const char *const *const ARGV1 = NM_MAKE_STRV("rd.znet=,");
+ const char *const *const ARGV2 = NM_MAKE_STRV("rd.znet=foobar");
+ const char *const *const ARGV3 = NM_MAKE_STRV("rd.znet=qeth,0.0.0800,,,layer2=0,portno=1");
+ const char *const *const ARGV[] = {ARGV0, ARGV1, ARGV2, ARGV3};
+ guint i;
+
+ for (i = 0; i < G_N_ELEMENTS(ARGV); i++) {
+ gs_unref_hashtable GHashTable *connections = NULL;
+
+ connections = _parse_cons(ARGV[i]);
+ g_assert_cmpint(g_hash_table_size(connections), ==, 0);
+ }
+}
+
static void
test_bootif_ip(void)
{
@@ -2173,6 +2191,7 @@ main(int argc, char **argv)
g_test_add_func("/initrd/cmdline/rd_znet", test_rd_znet);
g_test_add_func("/initrd/cmdline/rd_znet/legacy", test_rd_znet_legacy);
g_test_add_func("/initrd/cmdline/rd_znet/no_ip", test_rd_znet_no_ip);
+ g_test_add_func("/initrd/cmdline/rd_znet/empty", test_rd_znet_malformed);
g_test_add_func("/initrd/cmdline/bootif/ip", test_bootif_ip);
g_test_add_func("/initrd/cmdline/bootif/no_ip", test_bootif_no_ip);
g_test_add_func("/initrd/cmdline/bootif/hwtype", test_bootif_hwtype);
--
2.30.2