connectivity: fix portal detection with multiple devices (rh #1619873)

This commit is contained in:
Thomas Haller 2018-12-11 12:03:09 +01:00
parent f7dd2de1a5
commit 79bc1f8f5e
2 changed files with 197 additions and 1 deletions

View File

@ -0,0 +1,191 @@
From 4887afbc39e8898e794311e691fecdb01b9312bc Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Mon, 3 Dec 2018 10:27:06 +0100
Subject: [PATCH 1/2] libnm: add nm_connectivity_state_cmp() helper
(cherry picked from commit 487ee687d5bba82ee1054d74961afe122260811f)
(cherry picked from commit 51b7b10d3dc81d2837aba14ebf0e92f6ccd2db11)
(cherry picked from commit c155f776fd38eb8acfff3ac03d2e648fbb92930b)
(cherry picked from commit 0d1b58e7085f1bed623cd7b9759449fe2273a2ac)
---
src/nm-connectivity.h | 15 +++++++++++
src/tests/test-general.c | 58 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 73 insertions(+)
diff --git a/src/nm-connectivity.h b/src/nm-connectivity.h
index d9a9f2338..148fb359d 100644
--- a/src/nm-connectivity.h
+++ b/src/nm-connectivity.h
@@ -24,6 +24,21 @@
#include "nm-dbus-interface.h"
+/*****************************************************************************/
+
+static inline int
+nm_connectivity_state_cmp (NMConnectivityState a, NMConnectivityState b)
+{
+ if (a == NM_CONNECTIVITY_PORTAL && b == NM_CONNECTIVITY_LIMITED)
+ return 1;
+ if (b == NM_CONNECTIVITY_PORTAL && a == NM_CONNECTIVITY_LIMITED)
+ return -1;
+ NM_CMP_DIRECT (a, b);
+ return 0;
+}
+
+/*****************************************************************************/
+
#define NM_TYPE_CONNECTIVITY (nm_connectivity_get_type ())
#define NM_CONNECTIVITY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CONNECTIVITY, NMConnectivity))
#define NM_CONNECTIVITY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_CONNECTIVITY, NMConnectivityClass))
diff --git a/src/tests/test-general.c b/src/tests/test-general.c
index bfa2ea739..76842ea25 100644
--- a/src/tests/test-general.c
+++ b/src/tests/test-general.c
@@ -29,6 +29,8 @@
#include "NetworkManagerUtils.h"
#include "nm-core-internal.h"
+#include "nm-connectivity.h"
+
#include "nm-test-utils-core.h"
/* Reference implementation for nm_utils_ip6_address_clear_host_address.
@@ -1729,6 +1731,60 @@ test_nm_utils_exp10 (void)
/*****************************************************************************/
+static void
+test_connectivity_state_cmp (void)
+{
+ NMConnectivityState a;
+
+#define _cmp(a, b, cmp) \
+ G_STMT_START { \
+ const NMConnectivityState _a = (a); \
+ const NMConnectivityState _b = (b); \
+ const int _cmp = (cmp); \
+ \
+ g_assert (NM_IN_SET (_cmp, -1, 0, 1)); \
+ g_assert_cmpint (nm_connectivity_state_cmp (_a, _b), ==, _cmp); \
+ g_assert_cmpint (nm_connectivity_state_cmp (_b, _a), ==, -_cmp); \
+ } G_STMT_END
+
+ for (a = NM_CONNECTIVITY_UNKNOWN; a <= NM_CONNECTIVITY_FULL; a++)
+ _cmp (a, a, 0);
+
+ _cmp (NM_CONNECTIVITY_UNKNOWN, NM_CONNECTIVITY_UNKNOWN, 0);
+ _cmp (NM_CONNECTIVITY_UNKNOWN, NM_CONNECTIVITY_NONE, -1);
+ _cmp (NM_CONNECTIVITY_UNKNOWN, NM_CONNECTIVITY_LIMITED, -1);
+ _cmp (NM_CONNECTIVITY_UNKNOWN, NM_CONNECTIVITY_PORTAL, -1);
+ _cmp (NM_CONNECTIVITY_UNKNOWN, NM_CONNECTIVITY_FULL, -1);
+
+ _cmp (NM_CONNECTIVITY_NONE, NM_CONNECTIVITY_UNKNOWN, 1);
+ _cmp (NM_CONNECTIVITY_NONE, NM_CONNECTIVITY_NONE, 0);
+ _cmp (NM_CONNECTIVITY_NONE, NM_CONNECTIVITY_LIMITED, -1);
+ _cmp (NM_CONNECTIVITY_NONE, NM_CONNECTIVITY_PORTAL, -1);
+ _cmp (NM_CONNECTIVITY_NONE, NM_CONNECTIVITY_FULL, -1);
+
+ _cmp (NM_CONNECTIVITY_LIMITED, NM_CONNECTIVITY_UNKNOWN, 1);
+ _cmp (NM_CONNECTIVITY_LIMITED, NM_CONNECTIVITY_NONE, 1);
+ _cmp (NM_CONNECTIVITY_LIMITED, NM_CONNECTIVITY_LIMITED, 0);
+ _cmp (NM_CONNECTIVITY_LIMITED, NM_CONNECTIVITY_PORTAL, -1);
+ _cmp (NM_CONNECTIVITY_LIMITED, NM_CONNECTIVITY_FULL, -1);
+
+ _cmp (NM_CONNECTIVITY_PORTAL, NM_CONNECTIVITY_UNKNOWN, 1);
+ _cmp (NM_CONNECTIVITY_PORTAL, NM_CONNECTIVITY_NONE, 1);
+ _cmp (NM_CONNECTIVITY_PORTAL, NM_CONNECTIVITY_LIMITED, 1);
+ _cmp (NM_CONNECTIVITY_PORTAL, NM_CONNECTIVITY_PORTAL, 0);
+ _cmp (NM_CONNECTIVITY_PORTAL, NM_CONNECTIVITY_FULL, -1);
+
+ _cmp (NM_CONNECTIVITY_FULL, NM_CONNECTIVITY_UNKNOWN, 1);
+ _cmp (NM_CONNECTIVITY_FULL, NM_CONNECTIVITY_NONE, 1);
+ _cmp (NM_CONNECTIVITY_FULL, NM_CONNECTIVITY_LIMITED, 1);
+ _cmp (NM_CONNECTIVITY_FULL, NM_CONNECTIVITY_PORTAL, 1);
+ _cmp (NM_CONNECTIVITY_FULL, NM_CONNECTIVITY_FULL, 0);
+
+#undef _cmp
+}
+
+/*****************************************************************************/
+
NMTST_DEFINE ();
int
@@ -1773,6 +1829,8 @@ main (int argc, char **argv)
g_test_add_func ("/general/stable-id/parse", test_stable_id_parse);
g_test_add_func ("/general/stable-id/generated-complete", test_stable_id_generated_complete);
+ g_test_add_func ("/core/general/test_connectivity_state_cmp", test_connectivity_state_cmp);
+
return g_test_run ();
}
--
2.19.2
From fcd310bb9bcd914848f72008913665a7324ad788 Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Mon, 3 Dec 2018 10:31:51 +0100
Subject: [PATCH 2/2] connectivity: fix determining the global connectivity
state
Since we determine the connectivity state of each device individually,
the global connectivity state is an aggregate of all these states.
I am not sure about considering here devices that don't have the (best)
default route for their respective address family. But anyway.
When we aggregate the best connectivity, we chose the numerical largest
value. That is wrong, because PORTAL is numerically smaller than
LIMITED.
That means, if you have two devices, one with connectivity LIMITED and
one with connectivity PORTAL, then LIMITED wrongly wins.
Fixes: 6b7e9f9b225e81d365fd95901a88a7bc59c1eb39
https://bugzilla.redhat.com/show_bug.cgi?id=1619873
(cherry picked from commit ade753d06f4d8cac3a9c374fc1d9a409e2bce904)
(cherry picked from commit d1e98e334dd71b8fafa2512911b737adffddf569)
(cherry picked from commit 18103b00d8dd6dd99c9ff17d03cdf568a56d6720)
(cherry picked from commit 7e0938d5bda212f93e312113673f69b414713b35)
---
src/nm-manager.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/src/nm-manager.c b/src/nm-manager.c
index f3bbebd0d..c38eb3e89 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -2451,11 +2451,23 @@ device_connectivity_changed (NMDevice *device,
NMConnectivityState state;
const GSList *devices;
- for (devices = priv->devices; devices; devices = devices->next) {
- state = nm_device_get_connectivity_state (NM_DEVICE (devices->data));
- if (state > best_state)
+ best_state = nm_device_get_connectivity_state (device);
+ if (best_state < NM_CONNECTIVITY_FULL) {
+ /* FIXME: is this really correct, to considere devices that don't have
+ * (the best) default route for connectivity checking? */
+ for (devices = priv->devices; devices; devices = devices->next) {
+ state = nm_device_get_connectivity_state (devices->data);
+ if (nm_connectivity_state_cmp (state, best_state) <= 0)
+ continue;
best_state = state;
+ if (nm_connectivity_state_cmp (best_state, NM_CONNECTIVITY_FULL) >= 0) {
+ /* it doesn't get better than this. */
+ break;
+ }
+ }
}
+ nm_assert (best_state <= NM_CONNECTIVITY_FULL);
+ nm_assert (nm_connectivity_state_cmp (best_state, NM_CONNECTIVITY_FULL) <= 0);
if (best_state != priv->connectivity_state) {
priv->connectivity_state = best_state;
--
2.19.2

View File

@ -9,7 +9,7 @@
%global epoch_version 1
%global rpm_version 1.10.12
%global real_version 1.10.12
%global release_version 2
%global release_version 3
%global snapshot %{nil}
%global git_sha %{nil}
@ -93,6 +93,7 @@ Source3: 20-connectivity-fedora.conf
#Patch1: 0001-some.patch
Patch1: 0001-ifcfg-fix-crash-parsing-more-than-10-DNS-settings-in.patch
Patch2: 0002-dhcp-CVE-2018-15688.patch
Patch3: 0003-connectivity-check-rh1619873.patch
Requires(post): systemd
Requires(preun): systemd
@ -363,6 +364,7 @@ by nm-connection-editor and nm-applet in a non-graphical environment.
#%patch1 -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
%build
%if %{with regen_docs}
@ -715,6 +717,9 @@ fi
%endif
%changelog
* Tue Dec 11 2018 Thomas Haller <thaller@redhat.com> - 1:1.10.12-3
- connectivity: fix portal detection with multiple devices (rh #1619873)
* Mon Oct 29 2018 Thomas Haller <thaller@redhat.com> - 1:1.10.12-2
- ifcfg: fix crash parsing DNS entries (rh #1607866)
- dhcp: fix out-of-bounds heap write for DHCPv6 with internal plugin (CVE-2018-15688)