Fix CVE-2026-44943 and CVE-2026-44944 in iscsi-initiator-utils
Backport upstream fixes for two security vulnerabilities: - CVE-2026-44944: Fix iscsiuio control-socket credential verification to prevent unprivileged users from driving the iscsiuio control socket. - CVE-2026-44943: Validate IQN names received via discovery to prevent path traversal via crafted target names. Cherry-picked from upstream commits 668ca1df and 3f747d10, combined into a single patch (Patch105). CVE: CVE-2026-44944 Upstream patches: -668ca1df9c.patch -3f747d10ce.patch Resolves: RHEL-219473 This commit was backported by Ymir, a Red Hat Enterprise Linux software maintenance AI agent. Assisted-by: Ymir
This commit is contained in:
parent
b2600ddce3
commit
af319e91c3
250
iscsi-initiator-utils-6.2.1.11-CVE-2026-44944.patch
Normal file
250
iscsi-initiator-utils-6.2.1.11-CVE-2026-44944.patch
Normal file
@ -0,0 +1,250 @@
|
||||
From 5cb3d55b09287dad59892d5c49459a7a0a3d6e85 Mon Sep 17 00:00:00 2001
|
||||
From: Lee Duncan <lduncan@suse.com>
|
||||
Date: Tue, 14 Jul 2026 12:16:58 -0700
|
||||
Subject: [PATCH 1/2] Fix security issues recently discovered by Keith at
|
||||
Linneman Labs (#535)
|
||||
|
||||
* Fix iscsiuio control-socket credential verification.
|
||||
|
||||
Prevent unprivilidged user from driving the isscsiuio control socket,
|
||||
by validating connection against correct file descriptor.
|
||||
|
||||
Reference: CVE-2026-44944
|
||||
Found-by: <keith@linnemanlabs.com>
|
||||
|
||||
* Improve iscsid discovery handling of IQN names.
|
||||
|
||||
Currently, IQN names received via discovery are assumed to be valid up
|
||||
to the NULL character, i.e. the end of the supplied string. But this
|
||||
may not be correct.
|
||||
|
||||
The ASCII characters allowed in an IQN are detailed in RFC 3722, section
|
||||
6.2: "Currently Prohibited ASCII Characters".
|
||||
|
||||
Disallowing such characters should not break current usage, since the
|
||||
disallowed characters should not be in an IQN anyway. For example, they
|
||||
include characters like forward slashes, backward slashes, spaces,
|
||||
control characters, etc..
|
||||
|
||||
Open-iscsi uses target names as directory names in the "database"
|
||||
directory (typically /var/lib/iscsi), so fixing this eliminates discovery
|
||||
target name containing sequences like "../../../*" from being allowed.
|
||||
|
||||
Reference: CVE-2026-44943
|
||||
Found-by: <keith@linnemanlabs.com>
|
||||
---
|
||||
iscsiuio/src/unix/iscsid_ipc.c | 4 ++--
|
||||
usr/discovery.c | 18 ++++++++++++++++++
|
||||
usr/initiator.h | 3 +++
|
||||
usr/initiator_common.c | 33 +++++++++++++++++++++++++++++++++
|
||||
usr/iscsiadm.c | 4 ++++
|
||||
usr/iscsistart.c | 5 ++++-
|
||||
6 files changed, 64 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/iscsiuio/src/unix/iscsid_ipc.c b/iscsiuio/src/unix/iscsid_ipc.c
|
||||
index bcd6437..c4740fa 100644
|
||||
--- a/iscsiuio/src/unix/iscsid_ipc.c
|
||||
+++ b/iscsiuio/src/unix/iscsid_ipc.c
|
||||
@@ -1120,10 +1120,10 @@ static void *iscsid_loop(void *arg)
|
||||
continue;
|
||||
}
|
||||
|
||||
- if (!mgmt_peeruser(iscsid_opts.fd, user) || strncmp(user, "root", PEERUSER_MAX)) {
|
||||
+ if (!mgmt_peeruser(s2, user) || strncmp(user, "root", PEERUSER_MAX)) {
|
||||
close(s2);
|
||||
ILOG_ERR(PFX "Access error: non-administrative connection rejected");
|
||||
- break;
|
||||
+ continue;
|
||||
}
|
||||
|
||||
/* this closes the file descriptor s2 */
|
||||
diff --git a/usr/discovery.c b/usr/discovery.c
|
||||
index c163128..9317f39 100644
|
||||
--- a/usr/discovery.c
|
||||
+++ b/usr/discovery.c
|
||||
@@ -138,7 +138,9 @@ int discovery_isns_query(struct discovery_rec *drec, const char *iname,
|
||||
uint32_t status;
|
||||
int rc;
|
||||
|
||||
+
|
||||
isns_config.ic_security = 0;
|
||||
+
|
||||
source = isns_source_create_iscsi(iname);
|
||||
if (!source)
|
||||
return ISCSI_ERR_NOMEM;
|
||||
@@ -216,6 +218,11 @@ int discovery_isns_query(struct discovery_rec *drec, const char *iname,
|
||||
continue;
|
||||
}
|
||||
|
||||
+ if (!iqn_name_valid(pg_tgt)) {
|
||||
+ log_error("iSNS discovery Target Name invalid: ignoring it");
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
if (!isns_object_get_ipaddr(obj, ISNS_TAG_PG_PORTAL_IP_ADDR,
|
||||
&in_addr)) {
|
||||
log_debug(1, "Missing addr");
|
||||
@@ -294,6 +301,11 @@ static int discovery_isns_reg_node(const char *iname, int op_reg)
|
||||
log_debug(1, "trying to %s %s with iSNS server.",
|
||||
op_reg ? "register" : "deregister", iname);
|
||||
|
||||
+ if (!iqn_name_valid(iname)) {
|
||||
+ log_error("iSNS initiatorname invalid: ignoring it");
|
||||
+ return ISCSI_ERR_INVAL;
|
||||
+ }
|
||||
+
|
||||
source = isns_source_create_iscsi(iname);
|
||||
if (!source)
|
||||
return ISCSI_ERR_NOMEM;
|
||||
@@ -613,6 +625,12 @@ add_target_record(char *name, char *end, discovery_rec_t *drec,
|
||||
log_error("TargetName %s too long, ignoring", name);
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+ if (!iqn_name_valid(name)) {
|
||||
+ log_error("Discovery TargetName invalid, ignoring");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
text = name + length;
|
||||
|
||||
/* skip NULs after the name */
|
||||
diff --git a/usr/initiator.h b/usr/initiator.h
|
||||
index b174168..6c56a9f 100644
|
||||
--- a/usr/initiator.h
|
||||
+++ b/usr/initiator.h
|
||||
@@ -21,6 +21,7 @@
|
||||
#define INITIATOR_H
|
||||
|
||||
#include <stdint.h>
|
||||
+#include <stdbool.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
@@ -411,4 +412,6 @@ extern int iscsi_set_net_config(struct iscsi_transport *t,
|
||||
extern void iscsi_session_init_params(struct iscsi_session *session);
|
||||
|
||||
extern int session_in_use(int sid);
|
||||
+
|
||||
+extern bool iqn_name_valid(const char *name);
|
||||
#endif /* INITIATOR_H */
|
||||
diff --git a/usr/initiator_common.c b/usr/initiator_common.c
|
||||
index 80b7652..3d58023 100644
|
||||
--- a/usr/initiator_common.c
|
||||
+++ b/usr/initiator_common.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
+#include <stdbool.h>
|
||||
#include <libmount/libmount.h>
|
||||
|
||||
#include "iface.h"
|
||||
@@ -749,3 +750,35 @@ int iscsi_host_set_net_params(struct iface_rec *iface,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+/**
|
||||
+ * @brief iqn_name_valid -- return whether or not the supplied
|
||||
+ * IQN name valid
|
||||
+ *
|
||||
+ * @details Checks for invalid characters, using RFC 3722,
|
||||
+ * section 6.2, "Currently Prohibited ASCII Characters"
|
||||
+ *
|
||||
+ * @param name the IQN name we are checking
|
||||
+ * @return true iff the whole name (string) has valid
|
||||
+ * charaters
|
||||
+ */
|
||||
+bool
|
||||
+iqn_name_valid(const char *name)
|
||||
+{
|
||||
+ unsigned char *cp;
|
||||
+
|
||||
+ /* ensure no invalid characters */
|
||||
+ for (cp = name; *cp != '\0'; cp++)
|
||||
+ if ((*cp <= '\x2c') ||
|
||||
+ (*cp == '\x2f') ||
|
||||
+ ((*cp >= '\x3b') && (*cp <= '\x40')) ||
|
||||
+ ((*cp >= '\x5b') && (*cp <= '\x60')) ||
|
||||
+ (*cp >= '\x7b')) {
|
||||
+ log_debug(8, "IQN name is invalid: \"%s\" (char: '%#02x')",
|
||||
+ name, *cp);
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ log_debug(8, "IQN name has all valid characters: \"%s\"", name);
|
||||
+ return true;
|
||||
+}
|
||||
diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c
|
||||
index 340ac5a..d7b9234 100644
|
||||
--- a/usr/iscsiadm.c
|
||||
+++ b/usr/iscsiadm.c
|
||||
@@ -1165,6 +1165,10 @@ exec_disc_op_on_recs(discovery_rec_t *drec, struct list_head *rec_list,
|
||||
if (op & OP_NEW || op & OP_UPDATE) {
|
||||
/* now add/update records */
|
||||
list_for_each_entry(new_rec, rec_list, list) {
|
||||
+ if (!iqn_name_valid(new_rec->name)) {
|
||||
+ log_error("FW discovery Target Name invalid: ignoring it");
|
||||
+ continue;
|
||||
+ }
|
||||
rc = idbm_add_node(new_rec, drec, op & OP_UPDATE);
|
||||
if (rc)
|
||||
log_error("Could not add/update "
|
||||
diff --git a/usr/iscsistart.c b/usr/iscsistart.c
|
||||
index df92d24..6f133d6 100644
|
||||
--- a/usr/iscsistart.c
|
||||
+++ b/usr/iscsistart.c
|
||||
@@ -403,7 +403,10 @@ int main(int argc, char *argv[])
|
||||
case 't':
|
||||
check_str_param_len(optarg, TARGET_NAME_MAXLEN,
|
||||
"targetname");
|
||||
- strlcpy(config_rec.name, optarg, TARGET_NAME_MAXLEN);
|
||||
+ if (!iqn_name_valid(optarg))
|
||||
+ log_error("iscsistart Target Name invalid: ignoring");
|
||||
+ else
|
||||
+ strlcpy(config_rec.name, optarg, TARGET_NAME_MAXLEN);
|
||||
break;
|
||||
case 'g':
|
||||
config_rec.tpgt = atoi(optarg);
|
||||
|
||||
From 9ec7bda30472c1984140148cd432acd0c1c681fd Mon Sep 17 00:00:00 2001
|
||||
From: Cav4ever <303146950@qq.com>
|
||||
Date: Thu, 6 Aug 2026 03:05:15 +0800
|
||||
Subject: [PATCH 2/2] usr: Fix -Wdiscarded-qualifiers warning in iqn_name_valid
|
||||
(#537)
|
||||
|
||||
The iqn_name_valid() function takes a const char * parameter, but
|
||||
assigns it to a non-const unsigned char * pointer, which triggers
|
||||
a -Werror=discarded-qualifiers build failure:
|
||||
|
||||
initiator_common.c:771:17: error: assignment discards 'const'
|
||||
qualifier from pointer target type [-Werror=discarded-qualifiers]
|
||||
771 | for (cp = name; *cp != '\0'; cp++)
|
||||
|
||||
Fix this by declaring cp as const unsigned char * and adding an
|
||||
explicit cast.
|
||||
|
||||
Signed-off-by: Kou Wenqi <kouwenqi@kylinos.cn>
|
||||
Co-authored-by: Kou Wenqi <kouwenqi@kylinos.cn>
|
||||
---
|
||||
usr/initiator_common.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/usr/initiator_common.c b/usr/initiator_common.c
|
||||
index 3d58023..7502240 100644
|
||||
--- a/usr/initiator_common.c
|
||||
+++ b/usr/initiator_common.c
|
||||
@@ -765,10 +765,10 @@ int iscsi_host_set_net_params(struct iface_rec *iface,
|
||||
bool
|
||||
iqn_name_valid(const char *name)
|
||||
{
|
||||
- unsigned char *cp;
|
||||
+ const unsigned char *cp;
|
||||
|
||||
/* ensure no invalid characters */
|
||||
- for (cp = name; *cp != '\0'; cp++)
|
||||
+ for (cp = (const unsigned char *)name; *cp != '\0'; cp++)
|
||||
if ((*cp <= '\x2c') ||
|
||||
(*cp == '\x2f') ||
|
||||
((*cp >= '\x3b') && (*cp <= '\x40')) ||
|
||||
@ -10,7 +10,7 @@
|
||||
Summary: iSCSI daemon and utility programs
|
||||
Name: iscsi-initiator-utils
|
||||
Version: 6.%{open_iscsi_version}.%{open_iscsi_build}
|
||||
Release: 3.git%{shortcommit0}%{?dist}
|
||||
Release: 4.git%{shortcommit0}%{?dist}
|
||||
License: GPL-2.0-or-later
|
||||
URL: https://github.com/open-iscsi/open-iscsi
|
||||
Source0: https://github.com/open-iscsi/open-iscsi/archive/%{commit0}.tar.gz#/open-iscsi-%{shortcommit0}.tar.gz
|
||||
@ -44,6 +44,7 @@ Patch103: 0103-fix-libiscsi-firmware-discovery-issue-with-NULL-drec.patch
|
||||
Patch104: 0104-libiscsi-build-fixes.patch
|
||||
|
||||
# https://issues.redhat.com/browse/RHEL-219480
|
||||
# https://issues.redhat.com/browse/RHEL-219473
|
||||
# https://github.com/open-iscsi/open-iscsi/commit/668ca1df9c9a1e9bdd5c999ae1d67c9c8909237e
|
||||
# https://github.com/open-iscsi/open-iscsi/commit/3f747d10ce743483a5d5e9512eb28a08b12d9677
|
||||
Patch105: iscsi-initiator-utils-6.2.1.11-CVE-2026-44943.patch
|
||||
@ -282,6 +283,9 @@ systemctl --no-reload preset iscsi.service iscsi-starter.service &>/dev/null ||
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Tue Aug 11 2026 RHEL Packaging Agent <redhat-ymir-agent@redhat.com> - 6.2.1.11-4.git4b3e853
|
||||
- Fix CVE-2026-44943 and CVE-2026-44944
|
||||
|
||||
* Tue Aug 11 2026 RHEL Packaging Agent <redhat-ymir-agent@redhat.com> - 6.2.1.11-3.git4b3e853
|
||||
- Fix IQN name validation (CVE-2026-44943)
|
||||
- Fix iscsiuio control-socket credential verification (CVE-2026-44944)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user