From nobody Thu Feb 24 21:24:50 2022 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id BA6B319D2E68; Thu, 24 Feb 2022 21:24:50 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4K4QsZ4qW1z4nKD; Thu, 24 Feb 2022 21:24:50 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1645737890; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=8JpVlTmH0KELrxNa4kHIoKgKPiHTdBF3zslu89g2mlU=; b=wdCTA2IpgJxN+yscvoGKDEVMf9o1vRss6rQYRjhSbTjgG6o75CIrBNXuu8VnomEvkwWZKb UGnVn65I8Hk/Nby7ko2j2QJSYolW1oFjoymSt207pBvOTneUwH0/U7LcC3A2VpzQVvDlk8 ctJxmahksHFA51YWYCg+s9OEnKfHlbOy8Z+stCePybcLJuFhgnmJwfJpBhMMv/ekIC+pLp iEf/uxQuU33YPEdD3pokeoUGkZ2a3Jb0aQuH+PkATmZ/1zf47/g2y3L2bm0L6G16bMEbby +4vyK2Vx3prTWFX6dMrXqGrnm1WhwRIMPoNPl/JyYHRf8hbIZoGkZLhueuOq7w== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 802F213641; Thu, 24 Feb 2022 21:24:50 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 21OLOoR3016424; Thu, 24 Feb 2022 21:24:50 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 21OLOoTI016423; Thu, 24 Feb 2022 21:24:50 GMT (envelope-from git) Date: Thu, 24 Feb 2022 21:24:50 GMT Message-Id: <202202242124.21OLOoTI016423@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Alexander Motin Subject: git: 530d274c15e5 - main - CTL: Add length validation for incoming HA messages. List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: mav X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 530d274c15e5b3f69088b4b53f8dc5b2b849a916 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1645737890; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=8JpVlTmH0KELrxNa4kHIoKgKPiHTdBF3zslu89g2mlU=; b=BWY8rLe3wJT618/1Epkm6lH3kF4wZEv6jUd1ZQvC+Apf418pQqzbhVsVnJHiE6YJ1rg/IZ RLopOk3bEO5Wu+5/Wq9IWDTIY3HJ4mTjl5MVLuSwswpbYBWIpBt3RIE/9QKWei//OAOdyz JZcNviAUF52zSBRYc0jTf4B6XgqDzKqCXs7k9L3pOWxUELBMdfuPa8ZtKxWlsWhmT1ZdI2 XOI/e7Ecvhh45XHz9pBf5nGXy/VA/z02VdsEHzJJhhNAXA7teB0EqN5XbtFpOcP284ELx4 zF3KZhg0/O8IRAnBouynwS7RKMb01AmEK7tTtfU6o3wes04SNcNdiMaYpND1dQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1645737890; a=rsa-sha256; cv=none; b=vQ2/PRI6EVQZqad08C84r5uEr4bPQSKpvHaxWt9rW1XRs7ausMdanYfaZ5J5W/gU+xZWfM 0KeBuNiVJ0fvisrgmhOovt0sXi9p3yciodYXoX9E1vHWffhKEgf5mZx+ClARHw97zqSA98 Q+9bXjQerBdG55U8IXZLUTA53kVH6umUlmnuoZGURgI/Dy0LTr1V7rpiOcGhGX9RS97b4F 97v/gvlLocmNEyPTP4iI5J7PLmZyWwBQcnxJ/ip4kb8Jr/LOPmwrna6Hxprt9MaQPg6ewk QHrCB7UUFfPxwXKJPE1XwZ5WVOe3wDAeMzfS3q0SLLbGy1tgAWJ/ZBaDZqN6Vg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by mav: URL: https://cgit.FreeBSD.org/src/commit/?id=530d274c15e5b3f69088b4b53f8dc5b2b849a916 commit 530d274c15e5b3f69088b4b53f8dc5b2b849a916 Author: Alexander Motin AuthorDate: 2022-02-24 21:17:34 +0000 Commit: Alexander Motin CommitDate: 2022-02-24 21:24:43 +0000 CTL: Add length validation for incoming HA messages. This should fix uninitialized memory reads when working with broken HA peer, like one fixed in 1a8d8a3a909. Instead print error message and kill the HA link. MFC after: 3 days Sponsored by: iXsystems, Inc. --- sys/cam/ctl/ctl.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 4 deletions(-) diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index 96f598a8c740..a772c0fd92e1 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -1101,7 +1101,14 @@ static void ctl_isc_ua(struct ctl_softc *softc, union ctl_ha_msg *msg, int len) { struct ctl_lun *lun; - uint32_t iid = ctl_get_initindex(&msg->hdr.nexus); + uint32_t iid; + + if (len < sizeof(msg->ua)) { + printf("%s: Received truncated message %d < %lu\n", + __func__, len, sizeof(msg->ua)); + ctl_ha_msg_abort(CTL_HA_CHAN_CTL); + return; + } mtx_lock(&softc->ctl_lock); if (msg->hdr.nexus.targ_mapped_lun >= ctl_max_luns || @@ -1113,6 +1120,7 @@ ctl_isc_ua(struct ctl_softc *softc, union ctl_ha_msg *msg, int len) mtx_unlock(&softc->ctl_lock); if (msg->ua.ua_type == CTL_UA_THIN_PROV_THRES && msg->ua.ua_set) memcpy(lun->ua_tpt_info, msg->ua.ua_info, 8); + iid = ctl_get_initindex(&msg->hdr.nexus); if (msg->ua.ua_all) { if (msg->ua.ua_set) ctl_est_ua_all(lun, iid, msg->ua.ua_type); @@ -1136,6 +1144,20 @@ ctl_isc_lun_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len) ctl_lun_flags oflags; uint32_t targ_lun; + if (len < offsetof(struct ctl_ha_msg_lun, data[0])) { + printf("%s: Received truncated message %d < %lu\n", + __func__, len, offsetof(struct ctl_ha_msg_lun, data[0])); + ctl_ha_msg_abort(CTL_HA_CHAN_CTL); + return; + } + i = msg->lun.lun_devid_len + msg->lun.pr_key_count * sizeof(pr_key); + if (len < offsetof(struct ctl_ha_msg_lun, data[i])) { + printf("%s: Received truncated message data %d < %lu\n", + __func__, len, offsetof(struct ctl_ha_msg_lun, data[i])); + ctl_ha_msg_abort(CTL_HA_CHAN_CTL); + return; + } + targ_lun = msg->hdr.nexus.targ_mapped_lun; mtx_lock(&softc->ctl_lock); if (targ_lun >= ctl_max_luns || @@ -1206,6 +1228,22 @@ ctl_isc_port_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len) struct ctl_lun *lun; int i, new; + if (len < offsetof(struct ctl_ha_msg_port, data[0])) { + printf("%s: Received truncated message %d < %lu\n", + __func__, len, offsetof(struct ctl_ha_msg_port, data[0])); + ctl_ha_msg_abort(CTL_HA_CHAN_CTL); + return; + } + i = msg->port.name_len + msg->port.lun_map_len + + msg->port.port_devid_len + msg->port.target_devid_len + + msg->port.init_devid_len; + if (len < offsetof(struct ctl_ha_msg_port, data[i])) { + printf("%s: Received truncated message data %d < %lu\n", + __func__, len, offsetof(struct ctl_ha_msg_port, data[i])); + ctl_ha_msg_abort(CTL_HA_CHAN_CTL); + return; + } + port = softc->ctl_ports[msg->hdr.nexus.targ_port]; if (port == NULL) { CTL_DEBUG_PRINT(("%s: New port %d\n", __func__, @@ -1317,7 +1355,21 @@ static void ctl_isc_iid_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len) { struct ctl_port *port; - int iid; + int i, iid; + + if (len < offsetof(struct ctl_ha_msg_iid, data[0])) { + printf("%s: Received truncated message %d < %lu\n", + __func__, len, offsetof(struct ctl_ha_msg_iid, data[0])); + ctl_ha_msg_abort(CTL_HA_CHAN_CTL); + return; + } + i = msg->iid.name_len; + if (len < offsetof(struct ctl_ha_msg_iid, data[i])) { + printf("%s: Received truncated message data %d < %lu\n", + __func__, len, offsetof(struct ctl_ha_msg_iid, data[i])); + ctl_ha_msg_abort(CTL_HA_CHAN_CTL); + return; + } port = softc->ctl_ports[msg->hdr.nexus.targ_port]; if (port == NULL) { @@ -1343,6 +1395,13 @@ static void ctl_isc_login(struct ctl_softc *softc, union ctl_ha_msg *msg, int len) { + if (len < sizeof(msg->login)) { + printf("%s: Received truncated message %d < %lu\n", + __func__, len, sizeof(msg->login)); + ctl_ha_msg_abort(CTL_HA_CHAN_CTL); + return; + } + if (msg->login.version != CTL_HA_VERSION) { printf("CTL HA peers have different versions %d != %d\n", msg->login.version, CTL_HA_VERSION); @@ -1376,6 +1435,20 @@ ctl_isc_mode_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len) u_int i; uint32_t initidx, targ_lun; + if (len < offsetof(struct ctl_ha_msg_mode, data[0])) { + printf("%s: Received truncated message %d < %lu\n", + __func__, len, offsetof(struct ctl_ha_msg_mode, data[0])); + ctl_ha_msg_abort(CTL_HA_CHAN_CTL); + return; + } + i = msg->mode.page_len; + if (len < offsetof(struct ctl_ha_msg_mode, data[i])) { + printf("%s: Received truncated message data %d < %lu\n", + __func__, len, offsetof(struct ctl_ha_msg_mode, data[i])); + ctl_ha_msg_abort(CTL_HA_CHAN_CTL); + return; + } + targ_lun = msg->hdr.nexus.targ_mapped_lun; mtx_lock(&softc->ctl_lock); if (targ_lun >= ctl_max_luns || @@ -1400,7 +1473,7 @@ ctl_isc_mode_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len) return; } memcpy(lun->mode_pages.index[i].page_data, msg->mode.data, - lun->mode_pages.index[i].page_len); + min(lun->mode_pages.index[i].page_len, msg->mode.page_len)); initidx = ctl_get_initindex(&msg->hdr.nexus); if (initidx != -1) ctl_est_ua_all(lun, initidx, CTL_UA_MODE_CHANGE); @@ -1437,7 +1510,8 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param) return; } - CTL_DEBUG_PRINT(("CTL: msg_type %d\n", msg->hdr.msg_type)); + CTL_DEBUG_PRINT(("CTL: msg_type %d len %d\n", + msg->hdr.msg_type, param)); switch (msg->hdr.msg_type) { case CTL_MSG_SERIALIZE: io = ctl_alloc_io(softc->othersc_pool);