mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-09-28 10:50:15 +00:00
[Backport release-26.05] NetworkManager VPN plug-ins: Fix critical vulnerabilities (#565371)
This commit is contained in:
@@ -238,14 +238,13 @@ in
|
||||
default = [ ];
|
||||
example = literalExpression ''
|
||||
with pkgs; [
|
||||
networkmanager-fortisslvpn
|
||||
networkmanager-iodine
|
||||
networkmanager-libreswan
|
||||
networkmanager-l2tp
|
||||
networkmanager-openconnect
|
||||
networkmanager-openvpn
|
||||
networkmanager-sstp
|
||||
networkmanager-strongswan
|
||||
networkmanager-vpnc
|
||||
]
|
||||
'';
|
||||
description = ''
|
||||
|
||||
@@ -90,6 +90,9 @@ stdenv.mkDerivation rec {
|
||||
meta = {
|
||||
description = "NetworkManager’s FortiSSL plugin";
|
||||
inherit (networkmanager.meta) maintainers teams platforms;
|
||||
knownVulnerabilities = [
|
||||
"CVE-2026-91839"
|
||||
];
|
||||
license = lib.licenses.gpl2Plus;
|
||||
};
|
||||
}
|
||||
|
||||
203
pkgs/by-name/ne/networkmanager-iodine/CVE-2026-91837.patch
Normal file
203
pkgs/by-name/ne/networkmanager-iodine/CVE-2026-91837.patch
Normal file
@@ -0,0 +1,203 @@
|
||||
diff --git a/src/nm-iodine-service.c b/src/nm-iodine-service.c
|
||||
index 75a1610e4281588336985636a2dd4eda03575d3a..2cc74f6859304a895be0080dd50f72ddd29a8219 100644
|
||||
--- a/src/nm-iodine-service.c
|
||||
+++ b/src/nm-iodine-service.c
|
||||
@@ -468,14 +468,58 @@ send_password(gint fd, NMSettingVpn *s_vpn)
|
||||
}
|
||||
|
||||
|
||||
-static gint
|
||||
+static gboolean
|
||||
+label_is_valid (const gchar *label, gsize len)
|
||||
+{
|
||||
+ if (len == 0 || len > 63)
|
||||
+ return FALSE;
|
||||
+ if (label[0] == '-' || label[len - 1] == '-')
|
||||
+ return FALSE;
|
||||
+ for (gsize i = 0; i < len; i++)
|
||||
+ if (!g_ascii_isalnum (label[i]) && label[i] != '-')
|
||||
+ return FALSE;
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static gboolean
|
||||
+domain_is_valid (const gchar *domain)
|
||||
+{
|
||||
+ g_autofree char *ascii = NULL;
|
||||
+ g_auto (GStrv) labels = NULL;
|
||||
+
|
||||
+ if (domain == NULL || *domain == '\0')
|
||||
+ return FALSE;
|
||||
+
|
||||
+ /* Normalizes IDN labels to punycode; NULL on malformed UTF-8/encoding */
|
||||
+ ascii = g_hostname_to_ascii (domain);
|
||||
+ if (ascii == NULL)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (strlen (ascii) > 253)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ labels = g_strsplit (ascii, ".", -1);
|
||||
+ if (labels == NULL || labels[0] == NULL || labels[1] == NULL)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ for (int i = 0; labels[i] != NULL; i++) {
|
||||
+ if (!label_is_valid (labels[i], -1))
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static gboolean
|
||||
nm_iodine_start_iodine_binary (NMIodinePlugin *plugin,
|
||||
NMSettingVpn *s_vpn,
|
||||
GError **error)
|
||||
{
|
||||
GPid pid;
|
||||
const char **iodine_binary = NULL;
|
||||
- GPtrArray *iodine_argv;
|
||||
+ g_autoptr (GPtrArray) iodine_argv = g_ptr_array_new_full (12, NULL);
|
||||
GSource *iodine_watch;
|
||||
GIOChannel *stderr_channel;
|
||||
gint stdin_fd, stderr_fd;
|
||||
@@ -491,27 +535,20 @@ nm_iodine_start_iodine_binary (NMIodinePlugin *plugin,
|
||||
}
|
||||
|
||||
if (!*iodine_binary) {
|
||||
- g_set_error (error,
|
||||
- NM_VPN_PLUGIN_ERROR,
|
||||
- NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
|
||||
- "%s",
|
||||
- _("Could not find iodine binary."));
|
||||
- return -1;
|
||||
+ g_set_error_literal (error,
|
||||
+ NM_VPN_PLUGIN_ERROR,
|
||||
+ NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
|
||||
+ _("Could not find iodine binary."));
|
||||
+ return FALSE;
|
||||
}
|
||||
|
||||
props_fragsize = nm_setting_vpn_get_data_item (s_vpn, NM_IODINE_KEY_FRAGSIZE);
|
||||
props_nameserver = nm_setting_vpn_get_data_item (s_vpn, NM_IODINE_KEY_NAMESERVER);
|
||||
props_topdomain = nm_setting_vpn_get_data_item (s_vpn, NM_IODINE_KEY_TOPDOMAIN);
|
||||
- iodine_argv = g_ptr_array_new ();
|
||||
g_ptr_array_add (iodine_argv, (gpointer) (*iodine_binary));
|
||||
/* Run in foreground */
|
||||
g_ptr_array_add (iodine_argv, (gpointer) "-f");
|
||||
|
||||
- if (props_fragsize && strlen(props_fragsize)) {
|
||||
- g_ptr_array_add (iodine_argv, (gpointer) "-m");
|
||||
- g_ptr_array_add (iodine_argv, (gpointer) props_fragsize);
|
||||
- }
|
||||
-
|
||||
if (has_user(NM_IODINE_USER)) {
|
||||
g_ptr_array_add (iodine_argv, (gpointer) "-u");
|
||||
g_ptr_array_add (iodine_argv, (gpointer) NM_IODINE_USER);
|
||||
@@ -524,11 +561,51 @@ nm_iodine_start_iodine_binary (NMIodinePlugin *plugin,
|
||||
} else
|
||||
g_warning("Not running chrooted");
|
||||
|
||||
- if (props_nameserver && strlen(props_nameserver))
|
||||
- g_ptr_array_add (iodine_argv, (gpointer) props_nameserver);
|
||||
+ if (props_fragsize && strlen(props_fragsize)) {
|
||||
+ gchar *end = NULL;
|
||||
|
||||
- if (props_topdomain && strlen(props_topdomain))
|
||||
- g_ptr_array_add (iodine_argv, (gpointer) props_topdomain);
|
||||
+ (void)g_ascii_strtoll(props_fragsize, &end, 10);
|
||||
+ if (end != props_fragsize || *end == '\0') {
|
||||
+ g_ptr_array_add (iodine_argv, (gpointer) "-m");
|
||||
+ g_ptr_array_add (iodine_argv, (gpointer) props_fragsize);
|
||||
+ } else {
|
||||
+ g_warning("Failed to parse fragment size");
|
||||
+ g_set_error (error,
|
||||
+ NM_VPN_PLUGIN_ERROR,
|
||||
+ NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
|
||||
+ _("Invalid fragment size '%s'"),
|
||||
+ props_fragsize);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (props_nameserver && strlen(props_nameserver)) {
|
||||
+ g_autoptr (GInetAddress) addr = g_inet_address_new_from_string (props_nameserver);
|
||||
+
|
||||
+ if (addr) {
|
||||
+ g_ptr_array_add (iodine_argv, (gpointer) props_nameserver);
|
||||
+ } else {
|
||||
+ g_set_error (error,
|
||||
+ NM_VPN_PLUGIN_ERROR,
|
||||
+ NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
|
||||
+ _("Invalid nameserver '%s'"),
|
||||
+ props_nameserver);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (props_topdomain && strlen(props_topdomain)) {
|
||||
+ if (domain_is_valid (props_topdomain))
|
||||
+ g_ptr_array_add (iodine_argv, (gpointer) props_topdomain);
|
||||
+ else {
|
||||
+ g_set_error (error,
|
||||
+ NM_VPN_PLUGIN_ERROR,
|
||||
+ NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
|
||||
+ _("Invalid domain '%s'"),
|
||||
+ props_topdomain);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
g_ptr_array_add (iodine_argv, NULL);
|
||||
|
||||
@@ -536,11 +613,9 @@ nm_iodine_start_iodine_binary (NMIodinePlugin *plugin,
|
||||
G_SPAWN_DO_NOT_REAP_CHILD,
|
||||
NULL, NULL,
|
||||
&pid, &stdin_fd, NULL, &stderr_fd, error)) {
|
||||
- g_ptr_array_free (iodine_argv, TRUE);
|
||||
g_warning ("iodine failed to start. error: '%s'", (*error)->message);
|
||||
- return -1;
|
||||
+ return FALSE;
|
||||
}
|
||||
- g_ptr_array_free (iodine_argv, TRUE);
|
||||
|
||||
g_message ("iodine started with pid %d", pid);
|
||||
|
||||
@@ -556,13 +631,13 @@ nm_iodine_start_iodine_binary (NMIodinePlugin *plugin,
|
||||
priv->pid = pid;
|
||||
iodine_watch = g_child_watch_source_new (pid);
|
||||
g_source_set_callback (iodine_watch,
|
||||
- (GSourceFunc) iodine_watch_cb,
|
||||
+ G_SOURCE_FUNC (iodine_watch_cb),
|
||||
plugin,
|
||||
NULL);
|
||||
g_source_attach (iodine_watch, NULL);
|
||||
g_source_unref (iodine_watch);
|
||||
|
||||
- return 0;
|
||||
+ return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -572,7 +647,7 @@ real_connect (NMVpnServicePlugin *plugin,
|
||||
{
|
||||
NMSettingVpn *s_vpn;
|
||||
NMIodinePluginPrivate *priv = nm_iodine_plugin_get_instance_private (NM_IODINE_PLUGIN(plugin));
|
||||
- gint ret = -1;
|
||||
+ gboolean success;
|
||||
|
||||
g_variant_builder_init(&priv->ip4config, G_VARIANT_TYPE_VARDICT);
|
||||
|
||||
@@ -584,8 +659,8 @@ real_connect (NMVpnServicePlugin *plugin,
|
||||
if (!nm_iodine_secrets_validate (s_vpn, error))
|
||||
goto out;
|
||||
|
||||
- ret = nm_iodine_start_iodine_binary (NM_IODINE_PLUGIN (plugin), s_vpn, error);
|
||||
- if (!ret)
|
||||
+ success = nm_iodine_start_iodine_binary (NM_IODINE_PLUGIN (plugin), s_vpn, error);
|
||||
+ if (success)
|
||||
return TRUE;
|
||||
|
||||
out:
|
||||
@@ -32,6 +32,10 @@ stdenv.mkDerivation {
|
||||
(replaceVars ./fix-paths.patch {
|
||||
inherit iodine;
|
||||
})
|
||||
|
||||
# https://gitlab.gnome.org/GNOME/network-manager-iodine/-/issues/4
|
||||
# https://gitlab.gnome.org/GNOME/network-manager-iodine/-/merge_requests/6
|
||||
./CVE-2026-91837.patch
|
||||
];
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
||||
48
pkgs/by-name/ne/networkmanager-libreswan/fix-paths.patch
Normal file
48
pkgs/by-name/ne/networkmanager-libreswan/fix-paths.patch
Normal file
@@ -0,0 +1,48 @@
|
||||
diff --git a/properties/nm-libreswan-editor-plugin.c b/properties/nm-libreswan-editor-plugin.c
|
||||
index 6a178af..787e183 100644
|
||||
--- a/properties/nm-libreswan-editor-plugin.c
|
||||
+++ b/properties/nm-libreswan-editor-plugin.c
|
||||
@@ -96,7 +96,7 @@ export_to_file(NMVpnEditorPlugin *self, const char *path, NMConnection *connecti
|
||||
|
||||
openswan = nm_streq(nm_setting_vpn_get_service_type(s_vpn), NM_VPN_SERVICE_TYPE_OPENSWAN);
|
||||
|
||||
- nm_libreswan_detect_version(nm_libreswan_find_helper_bin("ipsec", NULL),
|
||||
+ nm_libreswan_detect_version("@ipsec@",
|
||||
&is_openswan,
|
||||
&version,
|
||||
NULL);
|
||||
diff --git a/src/nm-libreswan-service.c b/src/nm-libreswan-service.c
|
||||
index 0458d4e..e0add02 100644
|
||||
--- a/src/nm-libreswan-service.c
|
||||
+++ b/src/nm-libreswan-service.c
|
||||
@@ -1820,7 +1820,7 @@ connect_step(NMLibreswanPlugin *self, GError **error)
|
||||
if (!priv->openswan) {
|
||||
const char *stackman_path;
|
||||
|
||||
- stackman_path = nm_libreswan_find_helper_libexec("_stackmanager", error);
|
||||
+ stackman_path = "@libreswan@/libexec/_stackmanager";
|
||||
if (!stackman_path)
|
||||
return FALSE;
|
||||
|
||||
@@ -1977,7 +1977,7 @@ _connect_common(NMVpnServicePlugin *plugin,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
- priv->ipsec_path = nm_libreswan_find_helper_bin("ipsec", error);
|
||||
+ priv->ipsec_path = "@ipsec@";
|
||||
if (!priv->ipsec_path)
|
||||
return FALSE;
|
||||
|
||||
@@ -1988,10 +1988,10 @@ _connect_common(NMVpnServicePlugin *plugin,
|
||||
priv->openswan ? "Openswan" : "Libreswan");
|
||||
|
||||
if (!priv->openswan) {
|
||||
- priv->pluto_path = nm_libreswan_find_helper_libexec("pluto", error);
|
||||
+ priv->pluto_path = "@libreswan@/libexec/pluto";
|
||||
if (!priv->pluto_path)
|
||||
return FALSE;
|
||||
- priv->whack_path = nm_libreswan_find_helper_libexec("whack", error);
|
||||
+ priv->whack_path = "@libreswan@/libexec/whack";
|
||||
if (!priv->whack_path)
|
||||
return FALSE;
|
||||
}
|
||||
85
pkgs/by-name/ne/networkmanager-libreswan/package.nix
Normal file
85
pkgs/by-name/ne/networkmanager-libreswan/package.nix
Normal file
@@ -0,0 +1,85 @@
|
||||
{
|
||||
dieHook,
|
||||
fetchpatch,
|
||||
fetchurl,
|
||||
glib,
|
||||
gnome,
|
||||
gtk3,
|
||||
gtk4,
|
||||
intltool,
|
||||
lib,
|
||||
libnl,
|
||||
libnma,
|
||||
libnma-gtk4,
|
||||
libreswan,
|
||||
libsecret,
|
||||
networkmanager,
|
||||
pkg-config,
|
||||
replaceVars,
|
||||
stdenv,
|
||||
withGnome ? true,
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "NetworkManager-libreswan";
|
||||
version = "1.2.31";
|
||||
|
||||
src = fetchurl {
|
||||
url = "mirror://gnome/sources/NetworkManager-libreswan/${lib.versions.majorMinor finalAttrs.version}/NetworkManager-libreswan-${finalAttrs.version}.tar.xz";
|
||||
hash = "sha256-5xq3zWruZoOqlDQusm5hQzv/3y2ml4LsptHCmdzDp28=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
(replaceVars ./fix-paths.patch {
|
||||
ipsec = lib.getExe' libreswan "ipsec";
|
||||
inherit libreswan;
|
||||
})
|
||||
];
|
||||
|
||||
nativeBuildInputs = [
|
||||
dieHook
|
||||
glib
|
||||
intltool
|
||||
pkg-config
|
||||
];
|
||||
|
||||
buildInputs = [
|
||||
libnl
|
||||
networkmanager
|
||||
]
|
||||
++ lib.optionals withGnome [
|
||||
gtk3
|
||||
gtk4
|
||||
libnma
|
||||
libnma-gtk4
|
||||
libsecret
|
||||
];
|
||||
|
||||
configureFlags = [
|
||||
"--with-gnome=${lib.boolToYesNo withGnome}"
|
||||
"--with-gtk4=${lib.boolToYesNo withGnome}"
|
||||
"--enable-absolute-paths"
|
||||
];
|
||||
|
||||
strictDeps = true;
|
||||
__structuredAttrs = true;
|
||||
|
||||
postPatch = ''
|
||||
echo "Ensuring that all helper paths lookups were replaced"
|
||||
! grep -lr nm_libreswan_find_helper --exclude 'utils.[ch]' || die "^ Found non-replaced helper lookup"
|
||||
'';
|
||||
|
||||
passthru = {
|
||||
updateScript = gnome.updateScript {
|
||||
packageName = "NetworkManager-libreswan";
|
||||
attrPath = "networkmanager-libreswan";
|
||||
};
|
||||
networkManagerPlugin = "VPN/nm-libreswan-service.name";
|
||||
};
|
||||
|
||||
meta = {
|
||||
description = "NetworkManager's libreswan plugin";
|
||||
inherit (networkmanager.meta) maintainers teams platforms;
|
||||
license = lib.licenses.gpl2Plus;
|
||||
};
|
||||
})
|
||||
@@ -78,6 +78,9 @@ stdenv.mkDerivation rec {
|
||||
meta = {
|
||||
description = "NetworkManager's sstp plugin";
|
||||
inherit (networkmanager.meta) maintainers teams platforms;
|
||||
knownVulnerabilities = [
|
||||
"CVE-2026-91838"
|
||||
];
|
||||
license = lib.licenses.gpl2Plus;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -70,6 +70,10 @@ stdenv.mkDerivation rec {
|
||||
|
||||
meta = {
|
||||
description = "NetworkManager's VPNC plugin";
|
||||
knownVulnerabilities = [
|
||||
"CVE-2026-91840"
|
||||
"CVE-2026-91841"
|
||||
];
|
||||
inherit (networkmanager.meta) maintainers teams platforms;
|
||||
license = lib.licenses.gpl2Plus;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user