From owner-svn-src-all@freebsd.org Sun Jul 7 18:31:54 2019 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 7C29D15EABC0; Sun, 7 Jul 2019 18:31:54 +0000 (UTC) (envelope-from mav@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) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 252F26C272; Sun, 7 Jul 2019 18:31:54 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id F3BB34F2A; Sun, 7 Jul 2019 18:31:53 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x67IVrUr068378; Sun, 7 Jul 2019 18:31:53 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x67IVrVj068377; Sun, 7 Jul 2019 18:31:53 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201907071831.x67IVrVj068377@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Sun, 7 Jul 2019 18:31:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r349815 - stable/12/sys/cam/scsi X-SVN-Group: stable-12 X-SVN-Commit-Author: mav X-SVN-Commit-Paths: stable/12/sys/cam/scsi X-SVN-Commit-Revision: 349815 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 252F26C272 X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.96 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.999,0]; NEURAL_HAM_SHORT(-0.96)[-0.958,0]; NEURAL_HAM_LONG(-1.00)[-1.000,0]; ASN(0.00)[asn:12874, ipnet:2000::/3, country:IT] X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 07 Jul 2019 18:31:54 -0000 Author: mav Date: Sun Jul 7 18:31:53 2019 New Revision: 349815 URL: https://svnweb.freebsd.org/changeset/base/349815 Log: MFC r349284: Make ELEMENT INDEX validation more strict. SES specifications tell: "The Additional Element Status descriptors shall be in the same order as the status elements in the Enclosure Status diagnostic page". It allows us to question ELEMENT INDEX that is lower then values we already processed. There are many SAS2 enclosures with this kind of problem. While there, add more specific error messages for cases when ELEMENT INDEX is obviously wrong. Also skip elements with INVALID bit set. Modified: stable/12/sys/cam/scsi/scsi_enc_ses.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/cam/scsi/scsi_enc_ses.c ============================================================================== --- stable/12/sys/cam/scsi/scsi_enc_ses.c Sun Jul 7 18:29:37 2019 (r349814) +++ stable/12/sys/cam/scsi/scsi_enc_ses.c Sun Jul 7 18:31:53 2019 (r349815) @@ -1681,7 +1681,6 @@ ses_process_elm_addlstatus(enc_softc_t *enc, struct en struct ses_iterator iter, titer; int eip; int err; - int ignore_index = 0; int length; int offset; enc_cache_t *enc_cache; @@ -1752,7 +1751,7 @@ ses_process_elm_addlstatus(enc_softc_t *enc, struct en elm_hdr = (struct ses_elm_addlstatus_base_hdr *)&buf[offset]; eip = ses_elm_addlstatus_eip(elm_hdr); - if (eip && !ignore_index) { + if (eip) { struct ses_elm_addlstatus_eip_hdr *eip_hdr; int expected_index, index; ses_elem_index_type_t index_type; @@ -1765,17 +1764,44 @@ ses_process_elm_addlstatus(enc_softc_t *enc, struct en index_type = SES_ELEM_INDEX_INDIVIDUAL; expected_index = iter.individual_element_index; } + if (eip_hdr->element_index < expected_index) { + ENC_VLOG(enc, "%s: provided %selement index " + "%d is lower then expected %d\n", + __func__, (eip_hdr->byte2 & + SES_ADDL_EIP_EIIOE) ? "global " : "", + eip_hdr->element_index, expected_index); + goto badindex; + } titer = iter; telement = ses_iter_seek_to(&titer, eip_hdr->element_index, index_type); - if (telement != NULL && - (ses_typehasaddlstatus(enc, titer.type_index) != - TYPE_ADDLSTATUS_NONE || - titer.type_index > ELMTYP_SAS_CONN)) { + if (telement == NULL) { + ENC_VLOG(enc, "%s: provided %selement index " + "%d does not exist\n", __func__, + (eip_hdr->byte2 & SES_ADDL_EIP_EIIOE) ? + "global " : "", eip_hdr->element_index); + goto badindex; + } + if (ses_typehasaddlstatus(enc, titer.type_index) == + TYPE_ADDLSTATUS_NONE) { + ENC_VLOG(enc, "%s: provided %selement index " + "%d can't have additional status\n", + __func__, + (eip_hdr->byte2 & SES_ADDL_EIP_EIIOE) ? + "global " : "", eip_hdr->element_index); +badindex: + /* + * If we expected mandatory element, we may + * guess it was just a wrong index and we may + * use the status. If element was optional, + * then we have no idea where status belongs. + */ + if (status_type == TYPE_ADDLSTATUS_OPTIONAL) + break; + } else { iter = titer; element = telement; - } else - ignore_index = 1; + } if (eip_hdr->byte2 & SES_ADDL_EIP_EIIOE) index = iter.global_element_index; @@ -1797,35 +1823,41 @@ ses_process_elm_addlstatus(enc_softc_t *enc, struct en "type element index=%d, offset=0x%x, " "byte0=0x%x, length=0x%x\n", __func__, iter.global_element_index, iter.type_index, - iter.type_element_index, offset, elmpriv->addl.hdr->byte0, - elmpriv->addl.hdr->length); + iter.type_element_index, offset, elm_hdr->byte0, + elm_hdr->length); /* Skip to after the length field */ offset += sizeof(struct ses_elm_addlstatus_base_hdr); /* Make sure the descriptor is within bounds */ - if ((offset + elmpriv->addl.hdr->length) > length) { + if ((offset + elm_hdr->length) > length) { ENC_VLOG(enc, "Element %d Beyond End " "of Additional Element Status Descriptors\n", iter.global_element_index); break; } + /* Skip elements marked as invalid. */ + if (ses_elm_addlstatus_invalid(elm_hdr)) { + offset += elm_hdr->length; + continue; + } + /* Advance to the protocol data, skipping eip bytes if needed */ offset += (eip * SES_EIP_HDR_EXTRA_LEN); - proto_info_len = elmpriv->addl.hdr->length + proto_info_len = elm_hdr->length - (eip * SES_EIP_HDR_EXTRA_LEN); /* Errors in this block are ignored as they are non-fatal */ - switch(ses_elm_addlstatus_proto(elmpriv->addl.hdr)) { + switch(ses_elm_addlstatus_proto(elm_hdr)) { case SPSP_PROTO_FC: - if (elmpriv->addl.hdr->length == 0) + if (elm_hdr->length == 0) break; ses_get_elm_addlstatus_fc(enc, enc_cache, &buf[offset], proto_info_len); break; case SPSP_PROTO_SAS: - if (elmpriv->addl.hdr->length <= 2) + if (elm_hdr->length <= 2) break; ses_get_elm_addlstatus_sas(enc, enc_cache, &buf[offset], @@ -1836,7 +1868,7 @@ ses_process_elm_addlstatus(enc_softc_t *enc, struct en default: ENC_VLOG(enc, "Element %d: Unknown Additional Element " "Protocol 0x%x\n", iter.global_element_index, - ses_elm_addlstatus_proto(elmpriv->addl.hdr)); + ses_elm_addlstatus_proto(elm_hdr)); break; }