From nobody Tue Mar 29 01:51:03 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 4A8F31A40505; Tue, 29 Mar 2022 01:51:04 +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 4KSCG01g0bz3Ly5; Tue, 29 Mar 2022 01:51:04 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1648518664; 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=iee+q5scx/Cp3t+7GgVhwiIfyNbv4JlyviFynmwT3pc=; b=MRGnfZGwe7JVu6rfvuYEltSPuA7unxvOvB3Qy/OQxH8Y6IVa797nqXHS/zSOULHlyR78Cf 174/R5byHfpDJEgU69OyE9B8BkN8tZWZNdc2ucbggzCp3pg4MtkwPFMVrFlkwM7rLjJZLs fI+mgF3YLEqyUWk7JS6A+Z0eV883vNOkkik6NLFNY4Glos7/AKTwAnnXqJeECRWqzBrSxZ 5ERDxUCFsD6kpoeytKyJQCKHEoPVUKdkwR7cD4cBvI3gOQgIwY4ajBEE3wfymxBHeqafQm 3KWEJj2CJMmZVr9ULyUscwq5Yr3huEqmvyg4b5Jj0W1wj0BgXBnw1QToWHrh0Q== 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 19F951585B; Tue, 29 Mar 2022 01:51:04 +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 22T1p4bK031933; Tue, 29 Mar 2022 01:51:04 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 22T1p379031932; Tue, 29 Mar 2022 01:51:03 GMT (envelope-from git) Date: Tue, 29 Mar 2022 01:51:03 GMT Message-Id: <202203290151.22T1p379031932@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Alexander Motin Subject: git: 2f363712480e - stable/13 - 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/stable/13 X-Git-Reftype: branch X-Git-Commit: 2f363712480ed320188f3c55008eaafa18cf68fa Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1648518664; 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=iee+q5scx/Cp3t+7GgVhwiIfyNbv4JlyviFynmwT3pc=; b=KcsM9gGxE7+SfxyZAErcWmgYqIT6sXyLSJCBZ6t0jMRoaCPXZoI+1GjRvny/seS0GFSROT /sorTLkLXKf8pZaILMCndJ/vvABZZmnj3Be2dNZjEXX0Gufg3Ra1eigFSnwGgcy5VGwYg0 fOIvwL5KxiqaJYE0T4VRjgdFjb1gZcg4eDyZG9ep4X/sK4syZWcdjyDf+907Z3EKaBU8e7 YX+AnalwxdntxVW8XKia7KAMB6nN1uvr2rxhRTjRHUu5b0nrFdBJfZzeOTBtyjv8crv+Qr q8WXVw3DQKs2w4hF1ZgME6Yp7XLRk7HXwnTbwLaDg9fYpLEl2axfacwqvdaLrQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1648518664; a=rsa-sha256; cv=none; b=MeXYyfPb6XOnnwg5rQLnKp0cHskCPX3gElfV/huY3SI/4zSv5GKJ1Bk5RXC17CtAAfKME0 We4008SHYfAl3LI7v4M9wvpbZXpCUWbkDgNjljOezOkScJ5htWammkwfWv5EPjCnN7ZyBI tApkEsKhAvMy1HQhnxsWryZrMyNop5yajXMGexldf45N0NKkRb3rzXmSirz45G37esZ1Le h1mLomWG6Ith3usyncsfk23Ktmspa55yesTlGx3MVR7ltlG/tt/wcmj/z00U+FBQonVxRa l9SX7XK+NQeZr31UuQc/iOuCugk9ch1tdwQfo6SshNqCiNo5MNR45e0j0OLnzw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by mav: URL: https://cgit.FreeBSD.org/src/commit/?id=2f363712480ed320188f3c55008eaafa18cf68fa commit 2f363712480ed320188f3c55008eaafa18cf68fa Author: Alexander Motin AuthorDate: 2022-02-24 21:17:34 +0000 Commit: Alexander Motin CommitDate: 2022-03-29 01:30:48 +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. (cherry picked from commit 530d274c15e5b3f69088b4b53f8dc5b2b849a916) --- 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 c89c9a7863fe..8bdd4736254f 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);