From nobody Tue May 7 05:46:11 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) client-ip=170.10.133.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=canonical.com Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mx.zohomail.com with SMTPS id 1635533861852889.767595842433; Fri, 29 Oct 2021 11:57:41 -0700 (PDT) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-394-2fyZF3XvPuaOXMUmVADMmw-1; Fri, 29 Oct 2021 14:57:37 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 53D66814267; Fri, 29 Oct 2021 18:57:32 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 821B313ABD; Fri, 29 Oct 2021 18:57:31 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id D39DB4A703; Fri, 29 Oct 2021 18:57:27 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 19TIvP5D006371 for ; Fri, 29 Oct 2021 14:57:26 -0400 Received: by smtp.corp.redhat.com (Postfix) id D270E40CFD10; Fri, 29 Oct 2021 18:57:25 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast03.extmail.prod.ext.rdu2.redhat.com [10.11.55.19]) by smtp.corp.redhat.com (Postfix) with ESMTPS id CCE0040CFD0B for ; Fri, 29 Oct 2021 18:57:25 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-1.mimecast.com [207.211.31.81]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id A983E811E78 for ; Fri, 29 Oct 2021 18:57:25 +0000 (UTC) Received: from smtp-relay-internal-1.canonical.com (smtp-relay-internal-1.canonical.com [185.125.188.123]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-235-2D816gBiM1KTAPVKraDA2w-1; Fri, 29 Oct 2021 14:57:23 -0400 Received: from mail-lj1-f199.google.com (mail-lj1-f199.google.com [209.85.208.199]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id C65963F176 for ; Fri, 29 Oct 2021 18:57:21 +0000 (UTC) Received: by mail-lj1-f199.google.com with SMTP id x8-20020a2e5848000000b00212c1f21630so1023822ljd.20 for ; Fri, 29 Oct 2021 11:57:21 -0700 (PDT) Received: from ws.lan.d-node.is ([95.165.29.203]) by smtp.gmail.com with ESMTPSA id a28sm663983ljd.65.2021.10.29.11.57.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 Oct 2021 11:57:20 -0700 (PDT) X-MC-Unique: 2fyZF3XvPuaOXMUmVADMmw-1 X-MC-Unique: 2D816gBiM1KTAPVKraDA2w-1 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Dn2AaFBPHAk5NAmkAQPJKq1YwFnMCe9DEDDrkBWRr+k=; b=mRZhb4FsmM65YLre2QblPyicM0HIHJ1hxMU3BPT+4xYYdChhoW37xPMb/EjUjZzGsL ooNX4WdsGr/jX8GWckfWPHPWB9JaJ+sr+rU4XkN84nA0Zao9q7N7qXrwk76cETh62TCL ThYtprXLrptC+05MauTsk9FQ6Ew6EcaiYS/jIyijYK2ZeO397JvUd+Qdeo9UPJc9DPCL Nko+S/5MzWuj5UVMYMXaBI5F28dHGxW05z0CnxkHXLirY4KZboPTjpD/tI8yXsDKi24L 47LJI2W3qWLG46jFsMS5uAcMYA350Nx1e3j/PvQ7UU9uj4vFIL8WyfhaK5UW3DKvsmCT 3o1g== X-Gm-Message-State: AOAM531JkCZ3NHhF2ZujNMtTV2bGLcO+eOZ+VRwUo0D4+NrttrPlmq5C hG6PB3qUGQyeaH4Rsasypvxdy7wU3sgR6WFS16voj5oHlJbaNGA6uVNZLgFFT3QJtSbSfzErYnL HK0UYpvLe0H1K72vWCi4Qy/gcd2cYs/hVvg== X-Received: by 2002:ac2:4c89:: with SMTP id d9mr12049942lfl.421.1635533841138; Fri, 29 Oct 2021 11:57:21 -0700 (PDT) X-Google-Smtp-Source: ABdhPJySDD71nKB3erfvqGlE0Fq5bRF+oKmslFOuYRm0W9PzaFapEb05Pb8/rCNmLYZkAO4KoDn6uQ== X-Received: by 2002:ac2:4c89:: with SMTP id d9mr12049919lfl.421.1635533840843; Fri, 29 Oct 2021 11:57:20 -0700 (PDT) From: Dmitrii Shcherbakov To: libvir-list@redhat.com, dmitrii.shcherbakov@canonical.com Subject: [libvirt PATCH v2 1/3] PCI VPD: handle additional edge cases Date: Fri, 29 Oct 2021 21:57:16 +0300 Message-Id: <20211029185718.338025-2-dmitrii.shcherbakov@canonical.com> In-Reply-To: <20211029185718.338025-1-dmitrii.shcherbakov@canonical.com> References: <20211029185718.338025-1-dmitrii.shcherbakov@canonical.com> MIME-Version: 1.0 X-Mimecast-Impersonation-Protect: Policy=CLT - Impersonation Protection Definition; Similar Internal Domain=false; Similar Monitored External Domain=false; Custom External Domain=false; Mimecast External Domain=false; Newly Observed Domain=false; Internal User Name=false; Custom Display Name List=false; Reply-to Address Mismatch=false; Targeted Threat Dictionary=false; Mimecast Threat Dictionary=false; Custom Threat Dictionary=false X-Scanned-By: MIMEDefang 2.84 on 10.11.54.1 X-MIME-Autoconverted: from quoted-printable to 8bit by lists01.pubmisc.prod.ext.phx2.redhat.com id 19TIvP5D006371 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1635533864339100001 Content-Type: text/plain; charset="utf-8" * RV and RW fields must be at the last position in their respective section (per the conditions in the spec). Therefore, the parser now stops iterating over fields as soon as it encounters one of those fields and checks whether the end of the resource has been reached; * The lack of the RW field is not treated as a parsing error since we can still extract valid data even though this is a PCI/PCIe VPD spec violation; * Individual fields must have a valid length - the parser needs to check for invalid length values that violate boundary conditions of the resource. * A zero-length field may be the last one in the resource, however, the boundary check is currently too strict to allow that. Signed-off-by: Dmitrii Shcherbakov Tested-by: Daniel Henrique Barboza --- src/util/virpcivpd.c | 41 ++++++++++--- tests/virpcivpdtest.c | 137 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+), 9 deletions(-) diff --git a/src/util/virpcivpd.c b/src/util/virpcivpd.c index 8856bca459..4c96bc1a06 100644 --- a/src/util/virpcivpd.c +++ b/src/util/virpcivpd.c @@ -466,8 +466,12 @@ virPCIVPDParseVPDLargeResourceFields(int vpdFileFd, ui= nt16_t resPos, uint16_t re =20 bool hasChecksum =3D false; bool hasRW =3D false; + bool endReached =3D false; =20 - while (fieldPos + 3 < resPos + resDataLen) { + /* Note the equal sign - fields may have a zero length in which case t= hey will + * just occupy 3 header bytes. In the in case of the RW field this may= mean that + * no more space is left in the section. */ + while (fieldPos + 3 <=3D resPos + resDataLen) { /* Keyword resources consist of keywords (2 ASCII bytes per the sp= ec) and 1-byte length. */ if (virPCIVPDReadVPDBytes(vpdFileFd, buf, 3, fieldPos, csum) !=3D = 3) { /* Invalid field encountered which means the resource itself i= s invalid too. Report @@ -518,6 +522,13 @@ virPCIVPDParseVPDLargeResourceFields(int vpdFileFd, ui= nt16_t resPos, uint16_t re return false; } =20 + if (resPos + resDataLen < fieldPos + fieldDataLen) { + /* In this case the field cannot simply be skipped since the p= osition of the + * next field is determined based on the length of a previous = field. */ + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("A field data length violates the resource le= ngth boundary.")); + return false; + } if (virPCIVPDReadVPDBytes(vpdFileFd, buf, bytesToRead, fieldPos, c= sum) !=3D bytesToRead) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not parse a resource field data - VPD = has invalid format")); @@ -546,12 +557,13 @@ virPCIVPDParseVPDLargeResourceFields(int vpdFileFd, u= int16_t resPos, uint16_t re hasChecksum =3D true; g_free(g_steal_pointer(&fieldKeyword)); g_free(g_steal_pointer(&fieldValue)); - continue; + break; } else if (fieldFormat =3D=3D VIR_PCI_VPD_RESOURCE_FIELD_VALUE_FOR= MAT_RDWR) { /* Skip the read-write space since it is used for indication o= nly. */ hasRW =3D true; g_free(g_steal_pointer(&fieldKeyword)); g_free(g_steal_pointer(&fieldValue)); + break; } else if (fieldFormat =3D=3D VIR_PCI_VPD_RESOURCE_FIELD_VALUE_FOR= MAT_LAST) { /* Skip unknown fields */ g_free(g_steal_pointer(&fieldKeyword)); @@ -579,14 +591,25 @@ virPCIVPDParseVPDLargeResourceFields(int vpdFileFd, u= int16_t resPos, uint16_t re g_free(g_steal_pointer(&fieldKeyword)); g_free(g_steal_pointer(&fieldValue)); } - if (readOnly && !hasChecksum) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("VPD-R does not contain the mandatory RV field")); - return false; - } else if (!readOnly && !hasRW) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("VPD-W does not contain the mandatory RW field")); + + /* May have exited the loop prematurely in case RV or RW were encounte= red and + * they were not the last fields in the section. */ + endReached =3D (fieldPos >=3D resPos + resDataLen); + if (readOnly && !(hasChecksum && endReached)) { + VIR_DEBUG("VPD-R does not contain the mandatory RV field as the la= st field"); return false; + } else if (!readOnly && !endReached) { + /* The lack of RW is allowed on purpose in the read-write section = since some vendors + * violate the PCI/PCIe specs and do not include it, however, this= does not prevent parsing + * of valid data. If the RW is present, however, we make sure it i= s the last field in + * the read-write section. */ + if (hasRW) { + VIR_DEBUG("VPD-W section parsing ended prematurely (RW is not = the last field)."); + return false; + } else { + VIR_DEBUG("VPD-W section parsing ended prematurely."); + return false; + } } =20 return true; diff --git a/tests/virpcivpdtest.c b/tests/virpcivpdtest.c index 2cc9069132..a99bde2b92 100644 --- a/tests/virpcivpdtest.c +++ b/tests/virpcivpdtest.c @@ -597,6 +597,107 @@ testVirPCIVPDParseFullVPD(const void *opaque G_GNUC_U= NUSED) return ret; } =20 +static int +testVirPCIVPDParseZeroLengthRW(const void *opaque G_GNUC_UNUSED) +{ + int fd =3D -1; + size_t dataLen =3D 0; + + g_autoptr(virPCIVPDResource) res =3D NULL; + virPCIVPDResourceCustom *custom =3D NULL; + + /* The RW field has a zero length which means there is no more RW spa= ce left. */ + const uint8_t fullVPDExample[] =3D { + VPD_STRING_RESOURCE_EXAMPLE_HEADER, VPD_STRING_RESOURCE_EXAMPLE_DA= TA, + VPD_R_FIELDS_EXAMPLE_HEADER, VPD_R_FIELDS_EXAMPLE_DATA, + PCI_VPD_LARGE_RESOURCE_FLAG | PCI_VPD_READ_WRITE_LARGE_RESOURCE_FL= AG, 0x08, 0x00, + 'V', 'Z', 0x02, '4', '2', + 'R', 'W', 0x00, + PCI_VPD_RESOURCE_END_VAL + }; + + dataLen =3D sizeof(fullVPDExample) / sizeof(uint8_t); + fd =3D virCreateAnonymousFile(fullVPDExample, dataLen); + res =3D virPCIVPDParse(fd); + VIR_FORCE_CLOSE(fd); + + if (!res) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "The resource pointer is NULL after parsing which i= s unexpected"); + return -1; + } + + if (!res->ro) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "Read-only keywords are missing from the VPD resource."); + return -1; + } else if (!res->rw) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "Read-write keywords are missing from the VPD resource."); + return -1; + } + + if (testVirPCIVPDValidateExampleReadOnlyFields(res)) + return -1; + + custom =3D g_ptr_array_index(res->rw->vendor_specific, 0); + if (custom->idx !=3D 'Z' || STRNEQ_NULLABLE(custom->value, "42")) + return -1; + + custom =3D NULL; + return 0; +} + +static int +testVirPCIVPDParseNoRW(const void *opaque G_GNUC_UNUSED) +{ + int fd =3D -1; + size_t dataLen =3D 0; + + g_autoptr(virPCIVPDResource) res =3D NULL; + virPCIVPDResourceCustom *custom =3D NULL; + + /* The RW field has a zero length which means there is no more RW spa= ce left. */ + const uint8_t fullVPDExample[] =3D { + VPD_STRING_RESOURCE_EXAMPLE_HEADER, VPD_STRING_RESOURCE_EXAMPLE_DA= TA, + VPD_R_FIELDS_EXAMPLE_HEADER, VPD_R_FIELDS_EXAMPLE_DATA, + PCI_VPD_LARGE_RESOURCE_FLAG | PCI_VPD_READ_WRITE_LARGE_RESOURCE_FL= AG, 0x05, 0x00, + 'V', 'Z', 0x02, '4', '2', + PCI_VPD_RESOURCE_END_VAL + }; + + dataLen =3D sizeof(fullVPDExample) / sizeof(uint8_t); + fd =3D virCreateAnonymousFile(fullVPDExample, dataLen); + res =3D virPCIVPDParse(fd); + VIR_FORCE_CLOSE(fd); + + if (!res) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "The resource pointer is NULL after parsing which i= s unexpected"); + return -1; + } + + if (!res->ro) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "Read-only keywords are missing from the VPD resource."); + return -1; + } else if (!res->rw) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "Read-write keywords are missing from the VPD resource."); + return -1; + } + + if (testVirPCIVPDValidateExampleReadOnlyFields(res)) + return -1; + + custom =3D g_ptr_array_index(res->rw->vendor_specific, 0); + if (custom->idx !=3D 'Z' || STRNEQ_NULLABLE(custom->value, "42")) + return -1; + + custom =3D NULL; + return 0; +} + static int testVirPCIVPDParseFullVPDSkipInvalidKeywords(const void *opaque G_GNUC_UNU= SED) { @@ -717,6 +818,33 @@ testVirPCIVPDParseFullVPDInvalid(const void *opaque G_= GNUC_UNUSED) 'R', 'V', 0x02, 0x8A, 0x00, \ PCI_VPD_RESOURCE_END_VAL =20 +/* The SN field has a length field that goes past the resource boundaries.= */ +# define VPD_INVALID_SN_FIELD_LENGTH \ + VPD_STRING_RESOURCE_EXAMPLE_HEADER, \ + 't', 'e', 's', 't', 'n', 'a', 'm', 'e', \ + PCI_VPD_LARGE_RESOURCE_FLAG | PCI_VPD_READ_ONLY_LARGE_RESOURCE_FLAG, 0= x0A, 0x00, \ + 'S', 'N', 0x42, 0x04, 0x02, \ + 'R', 'V', 0x02, 0xE8, 0x00, \ + PCI_VPD_RESOURCE_END_VAL + +/* The RV field is not the last one in VPD-R while the checksum is valid. = */ +# define VPD_INVALID_RV_NOT_LAST \ + VPD_STRING_RESOURCE_EXAMPLE_HEADER, \ + 't', 'e', 's', 't', 'n', 'a', 'm', 'e', \ + PCI_VPD_LARGE_RESOURCE_FLAG | PCI_VPD_READ_ONLY_LARGE_RESOURCE_FLAG, 0= x0A, 0x00, \ + 'R', 'V', 0x02, 0xD1, 0x00, \ + 'S', 'N', 0x02, 0x04, 0x02, \ + PCI_VPD_RESOURCE_END_VAL + +# define VPD_INVALID_RW_NOT_LAST \ + VPD_STRING_RESOURCE_EXAMPLE_HEADER, VPD_STRING_RESOURCE_EXAMPLE_DATA, \ + VPD_R_FIELDS_EXAMPLE_HEADER, VPD_R_FIELDS_EXAMPLE_DATA, \ + PCI_VPD_LARGE_RESOURCE_FLAG | PCI_VPD_READ_WRITE_LARGE_RESOURCE_FLAG, = 0x08, 0x00, \ + 'R', 'W', 0x00, \ + 'V', 'Z', 0x02, '4', '2', \ + PCI_VPD_RESOURCE_END_VAL + + # define TEST_INVALID_VPD(invalidVPD) \ do { \ g_autoptr(virPCIVPDResource) res =3D NULL; \ @@ -741,6 +869,9 @@ testVirPCIVPDParseFullVPDInvalid(const void *opaque G_G= NUC_UNUSED) TEST_INVALID_VPD(VPD_R_UNEXPECTED_RW_IN_VPD_R_KEY); TEST_INVALID_VPD(VPD_R_INVALID_FIELD_VALUE); TEST_INVALID_VPD(VPD_INVALID_STRING_RESOURCE_VALUE); + TEST_INVALID_VPD(VPD_INVALID_SN_FIELD_LENGTH); + TEST_INVALID_VPD(VPD_INVALID_RV_NOT_LAST); + TEST_INVALID_VPD(VPD_INVALID_RW_NOT_LAST); =20 return 0; } @@ -767,6 +898,12 @@ mymain(void) ret =3D -1; if (virTestRun("Parsing VPD string resources ", testVirPCIVPDParseVPDS= tringResource, NULL) < 0) ret =3D -1; + if (virTestRun("Parsing a VPD resource with a zero-length RW ", + testVirPCIVPDParseZeroLengthRW, NULL) < 0) + ret =3D -1; + if (virTestRun("Parsing a VPD resource without an RW ", + testVirPCIVPDParseNoRW, NULL) < 0) + ret =3D -1; if (virTestRun("Parsing a VPD resource with an invalid keyword ", testVirPCIVPDParseFullVPDSkipInvalidKeywords, NULL) < 0) ret =3D -1; --=20 2.32.0 From nobody Tue May 7 05:46:11 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) client-ip=170.10.133.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=canonical.com Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mx.zohomail.com with SMTPS id 1635533867664646.5080115196242; Fri, 29 Oct 2021 11:57:47 -0700 (PDT) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-586-Z7na5uB5O06smwKM2l1G_w-1; Fri, 29 Oct 2021 14:57:43 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 904E1100A958; Fri, 29 Oct 2021 18:57:36 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 25110444F9; Fri, 29 Oct 2021 18:57:33 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 05B694A704; Fri, 29 Oct 2021 18:57:31 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 19TIvTd1006393 for ; Fri, 29 Oct 2021 14:57:29 -0400 Received: by smtp.corp.redhat.com (Postfix) id 0479D2026D69; Fri, 29 Oct 2021 18:57:29 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast02.extmail.prod.ext.rdu2.redhat.com [10.11.55.18]) by smtp.corp.redhat.com (Postfix) with ESMTPS id F24A72026D48 for ; Fri, 29 Oct 2021 18:57:28 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [205.139.110.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id CA6898007B1 for ; Fri, 29 Oct 2021 18:57:28 +0000 (UTC) Received: from smtp-relay-internal-1.canonical.com (smtp-relay-internal-1.canonical.com [185.125.188.123]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-30-xx39bZxZNK27DfUF4DhR4g-1; Fri, 29 Oct 2021 14:57:23 -0400 Received: from mail-lj1-f199.google.com (mail-lj1-f199.google.com [209.85.208.199]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id 540F33F177 for ; Fri, 29 Oct 2021 18:57:22 +0000 (UTC) Received: by mail-lj1-f199.google.com with SMTP id u21-20020a2e91d5000000b00210e16996e5so3498521ljg.5 for ; Fri, 29 Oct 2021 11:57:22 -0700 (PDT) Received: from ws.lan.d-node.is ([95.165.29.203]) by smtp.gmail.com with ESMTPSA id a28sm663983ljd.65.2021.10.29.11.57.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 Oct 2021 11:57:21 -0700 (PDT) X-MC-Unique: Z7na5uB5O06smwKM2l1G_w-1 X-MC-Unique: xx39bZxZNK27DfUF4DhR4g-1 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ZthdMD/kAJUv4EOcA8FzZSvgK8tH/N2CJFYnBJi2ZXs=; b=vZhLpibMkEOIpAmWxkFytsM45+Qo3lyldspVxlSjRK5PwNe2Wm64mLRNsJnMQxejz2 K+2N7lCLCpJ6/3BUASsvZ+rQvRdHelX6YXHILgv7WVdaQt9axhOkG9xtk1O1GL4zGjEH 9f9ednUBTl/7VH56G46gGbDVQXbu+oY+EOAV7rAARfpYb4Jn1Skrq9/Uh21bY+qAx1tr Y1c87ADK9nr488Ey78KMciJgC6TdawuBlBlFtmlIQD/lysZbh/qyevGSH9UHZF4VjX5e n9t2W4zxqfAN8WaEYid353+poamaFGIWkOGasLBA7fxamV2D06Vn1GFZgtLXwQOpjQGA 7Leg== X-Gm-Message-State: AOAM531tA5tbgBr+J6pgOMVQdWTbDDcIPhX8gbp1Kgn9VL4N47EePTn1 yZT4ZEblsC3troDNS/s6NLr0o/Ba34z50MkPBUc7anb8WSjItROb985nUVSvEaMXCWxBX7NCcdH 3d8l0KZoCxwU3JbwP/001GwuE0CV7hqtn8A== X-Received: by 2002:a2e:7d10:: with SMTP id y16mr13676909ljc.388.1635533841741; Fri, 29 Oct 2021 11:57:21 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwip0BBlxa4QpAoQ3UljBJ0HTv0tPhB2Jt20zJS8uRJN+rEUF8XmLtikoqbU0+4rvrs4sQY0A== X-Received: by 2002:a2e:7d10:: with SMTP id y16mr13676880ljc.388.1635533841462; Fri, 29 Oct 2021 11:57:21 -0700 (PDT) From: Dmitrii Shcherbakov To: libvir-list@redhat.com, dmitrii.shcherbakov@canonical.com Subject: [libvirt PATCH v2 2/3] PCI VPD: Skip fields with invalid values Date: Fri, 29 Oct 2021 21:57:17 +0300 Message-Id: <20211029185718.338025-3-dmitrii.shcherbakov@canonical.com> In-Reply-To: <20211029185718.338025-1-dmitrii.shcherbakov@canonical.com> References: <20211029185718.338025-1-dmitrii.shcherbakov@canonical.com> MIME-Version: 1.0 X-Mimecast-Impersonation-Protect: Policy=CLT - Impersonation Protection Definition; Similar Internal Domain=false; Similar Monitored External Domain=false; Custom External Domain=false; Mimecast External Domain=false; Newly Observed Domain=false; Internal User Name=false; Custom Display Name List=false; Reply-to Address Mismatch=false; Targeted Threat Dictionary=false; Mimecast Threat Dictionary=false; Custom Threat Dictionary=false X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-MIME-Autoconverted: from quoted-printable to 8bit by lists01.pubmisc.prod.ext.phx2.redhat.com id 19TIvTd1006393 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1635533868411100001 While invalid values need to be ignored when presenting VPD data to the user, it would be good to attempt to parse a valid portion of the VPD instead of marking it invalid as a whole. Based on a mailing list discussion, the set of accepted characters is extended to the set of printable ASCII characters. https://listman.redhat.com/archives/libvir-list/2021-October/msg01043.html The particular example encountered on real hardware was multi-faceted: * "N/A" strings present in read-only fields. This would not be a useful valid value for a field (especially if a unique serial number is expected), however, it was decided to delegate handling of those kinds of values to higher-level software; * "4W/1W PCIeG2x4" - looks like some vendors use even more printable characters in the ASCII range than we currently allow. Since the PCI/PCIe VPD specs mention alphanumeric characters without specifying the full character set, it looks like this is ambiguous for vendors and they tend to use printable ASCII characters; * 0xFF bytes present in VPD-W field values. Those bytes do not map to printable ASCII code points and were probably used by the vendor as placeholders. Ignoring the whole VPD because of that would be too strict. Signed-off-by: Dmitrii Shcherbakov Tested-by: Daniel Henrique Barboza --- src/util/virpcivpd.c | 22 +++++--- tests/virpcivpdtest.c | 125 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 127 insertions(+), 20 deletions(-) diff --git a/src/util/virpcivpd.c b/src/util/virpcivpd.c index 4c96bc1a06..d8f2a43cde 100644 --- a/src/util/virpcivpd.c +++ b/src/util/virpcivpd.c @@ -161,8 +161,6 @@ virPCIVPDResourceGetFieldValueFormat(const char *keywor= d) return format; } =20 -#define ACCEPTED_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX= YZ0123456789 -_,.:;=3D" - /** * virPCIVPDResourceIsValidTextValue: * @value: A NULL-terminated string to assess. @@ -175,6 +173,7 @@ virPCIVPDResourceGetFieldValueFormat(const char *keywor= d) bool virPCIVPDResourceIsValidTextValue(const char *value) { + size_t i =3D 0; /* * The PCI(e) specs mention alphanumeric characters when talking about= text fields * and the string resource but also include spaces and dashes in the p= rovided example. @@ -191,10 +190,12 @@ virPCIVPDResourceIsValidTextValue(const char *value) if (STREQ(value, "")) return true; =20 - if (strspn(value, ACCEPTED_CHARS) !=3D strlen(value)) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("The provided value contains invalid characters: = %s"), value); - return false; + while (i < strlen(value)) { + if (!g_ascii_isprint(value[i])) { + VIR_DEBUG("The provided value contains non-ASCII printable cha= racters: %s", value); + return false; + } + ++i; } return true; } @@ -544,9 +545,12 @@ virPCIVPDParseVPDLargeResourceFields(int vpdFileFd, ui= nt16_t resPos, uint16_t re */ fieldValue =3D g_strstrip(g_strndup((char *)buf, fieldDataLen)= ); if (!virPCIVPDResourceIsValidTextValue(fieldValue)) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Field value contains invalid characters"= )); - return false; + /* Skip fields with invalid values - this is safe assuming= field length is + * correctly specified. */ + VIR_DEBUG("A value for field %s contains invalid character= s", fieldKeyword); + g_free(g_steal_pointer(&fieldKeyword)); + g_free(g_steal_pointer(&fieldValue)); + continue; } } else if (fieldFormat =3D=3D VIR_PCI_VPD_RESOURCE_FIELD_VALUE_FOR= MAT_RESVD) { if (*csum) { diff --git a/tests/virpcivpdtest.c b/tests/virpcivpdtest.c index a99bde2b92..b7bc86d922 100644 --- a/tests/virpcivpdtest.c +++ b/tests/virpcivpdtest.c @@ -322,8 +322,10 @@ testPCIVPDIsValidTextValue(const void *data G_GNUC_UNU= SED) {"under_score_example", true}, {"", true}, {";", true}, - {"\\42", false}, - {"/42", false}, + {"\\42", true}, + {"N/A", true}, + /* The first and last code points are outside ASCII (multi-byte in= UTF-8). */ + {"=D0=B3bl=F0=9F=90=A7", false}, }; for (i =3D 0; i < sizeof(textValueCases) / sizeof(textValueCases[0]); = ++i) { if (virPCIVPDResourceIsValidTextValue(textValueCases[i].keyword) != =3D @@ -741,6 +743,113 @@ testVirPCIVPDParseFullVPDSkipInvalidKeywords(const vo= id *opaque G_GNUC_UNUSED) return 0; } =20 +static int +testVirPCIVPDParseFullVPDSkipInvalidValues(const void *opaque G_GNUC_UNUSE= D) +{ + int fd =3D -1; + size_t dataLen =3D 0; + size_t i =3D 0; + virPCIVPDResourceCustom *custom =3D NULL; + + g_autoptr(virPCIVPDResource) res =3D NULL; + + /* This example is based on real-world hardware which was programmed b= y the vendor with + * invalid field values in both the RO section and RW section. The RO = section contains + * fields that are not valid per the spec but accepted by Libvirt as p= rintable ASCII + * characters. The RW field has a 0 length which means there is no mor= e space in the + * RW section. */ + const uint8_t fullVPDExample[] =3D { + 0x82, 0x23, 0x00, 0x48, 0x50, 0x20, 0x45, 0x74, 0x68, 0x65, 0x72, = 0x6e, 0x65, 0x74, + 0x20, 0x31, 0x47, 0x62, 0x20, 0x32, 0x2d, 0x70, 0x6f, 0x72, 0x74, = 0x20, 0x33, 0x36, + 0x31, 0x69, 0x20, 0x41, 0x64, 0x61, 0x70, 0x74, 0x65, 0x72, 0x90, = 0x42, 0x00, 0x50, + 0x4e, 0x03, 0x4e, 0x2f, 0x41, 0x45, 0x43, 0x03, 0x4e, 0x2f, 0x41, = 0x53, 0x4e, 0x03, + 0x4e, 0x2f, 0x41, 0x56, 0x30, 0x29, 0x34, 0x57, 0x2f, 0x31, 0x57, = 0x20, 0x50, 0x43, + 0x49, 0x65, 0x47, 0x32, 0x78, 0x34, 0x20, 0x32, 0x70, 0x20, 0x31, = 0x47, 0x62, 0x45, + 0x20, 0x52, 0x4a, 0x34, 0x35, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x6c, = 0x20, 0x69, 0x33, + 0x35, 0x30, 0x20, 0x20, 0x20, 0x52, 0x56, 0x01, 0x63, 0x91, 0x47, = 0x00, 0x56, 0x31, + 0x06, 0x35, 0x2e, 0x37, 0x2e, 0x30, 0x36, 0x56, 0x33, 0x06, 0x32, = 0x2e, 0x38, 0x2e, + 0x32, 0x30, 0x56, 0x36, 0x06, 0x31, 0x2e, 0x35, 0x2e, 0x33, 0x35, = 0x59, 0x41, 0x03, + 0x4e, 0x2f, 0x41, 0x59, 0x42, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, = 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x59, 0x43, 0x0D, = 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 'R', '= W', 0x00, 0x78, + }; + + dataLen =3D sizeof(fullVPDExample) / sizeof(uint8_t); + fd =3D virCreateAnonymousFile(fullVPDExample, dataLen); + res =3D virPCIVPDParse(fd); + VIR_FORCE_CLOSE(fd); + + if (!res) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "The resource pointer is NULL after parsing which i= s unexpected."); + return -1; + } + /* Some values in the read-write section are invalid but parsing shoul= d succeed + * considering the parser is implemented to be graceful about invalid = keywords and + * values. */ + if (!res->ro) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "The RO section consisting of only invalid fields g= ot parsed successfully"); + return -1; + } + if (!res->rw) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "Could not successfully parse an RW section with so= me invalid fields"); + return -1; + } + + if (!STREQ_NULLABLE(res->ro->change_level, "N/A")) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "Could not parse a change level field with acceptab= le contents"); + return -1; + } + if (!STREQ_NULLABLE(res->ro->part_number, "N/A")) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "Could not parse a part number field with acceptabl= e contents"); + return -1; + } + if (!STREQ_NULLABLE(res->ro->serial_number, "N/A")) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "Could not parse a serial number with acceptable co= ntents"); + return -1; + } + if (!STREQ_NULLABLE(res->rw->asset_tag, "N/A")) { + /* The asset tag has an invalid value in this case so it should be= NULL. */ + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "Could not parse an asset tag with acceptable conte= nts"); + return -1; + } + if (res->rw->vendor_specific->len !=3D 3) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "The number of parsed vendor fields is not equal to= the expected number."); + return -1; + } + if (res->rw->system_specific->len > 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "Successfully parsed some systems-specific fields w= hile none are valid"); + return -1; + } + for (i =3D 0; i < res->rw->vendor_specific->len; ++i) { + custom =3D ((virPCIVPDResourceCustom*)g_ptr_array_index(res->rw->v= endor_specific, i)); + if (custom->idx =3D=3D '1') { + if (STRNEQ(custom->value, "5.7.06")) { + return -1; + } + } else if (custom->idx =3D=3D '3') { + if (STRNEQ(custom->value, "2.8.20")) { + return -1; + } + } else if (custom->idx =3D=3D '6') { + if (STRNEQ(custom->value, "1.5.35")) { + return -1; + } + } + } + + return 0; +} + + static int testVirPCIVPDParseFullVPDInvalid(const void *opaque G_GNUC_UNUSED) { @@ -802,14 +911,6 @@ testVirPCIVPDParseFullVPDInvalid(const void *opaque G_= GNUC_UNUSED) 'R', 'V', 0x02, 0x81, 0x00, \ PCI_VPD_RESOURCE_END_VAL =20 -# define VPD_R_INVALID_FIELD_VALUE \ - VPD_STRING_RESOURCE_EXAMPLE_HEADER, \ - VPD_STRING_RESOURCE_EXAMPLE_DATA, \ - PCI_VPD_LARGE_RESOURCE_FLAG | PCI_VPD_READ_ONLY_LARGE_RESOURCE_FLAG, 0= x0A, 0x00, \ - 'S', 'N', 0x02, 0x04, 0x02, \ - 'R', 'V', 0x02, 0x28, 0x00, \ - PCI_VPD_RESOURCE_END_VAL - # define VPD_INVALID_STRING_RESOURCE_VALUE \ VPD_STRING_RESOURCE_EXAMPLE_HEADER, \ 't', 0x03, 's', 't', 'n', 'a', 'm', 'e', \ @@ -867,7 +968,6 @@ testVirPCIVPDParseFullVPDInvalid(const void *opaque G_G= NUC_UNUSED) TEST_INVALID_VPD(VPD_R_INVALID_RV); TEST_INVALID_VPD(VPD_R_INVALID_RV_ZERO_LENGTH); TEST_INVALID_VPD(VPD_R_UNEXPECTED_RW_IN_VPD_R_KEY); - TEST_INVALID_VPD(VPD_R_INVALID_FIELD_VALUE); TEST_INVALID_VPD(VPD_INVALID_STRING_RESOURCE_VALUE); TEST_INVALID_VPD(VPD_INVALID_SN_FIELD_LENGTH); TEST_INVALID_VPD(VPD_INVALID_RV_NOT_LAST); @@ -904,6 +1004,9 @@ mymain(void) if (virTestRun("Parsing a VPD resource without an RW ", testVirPCIVPDParseNoRW, NULL) < 0) ret =3D -1; + if (virTestRun("Parsing a VPD resource with an invalid values ", + testVirPCIVPDParseFullVPDSkipInvalidValues, NULL) < 0) + ret =3D -1; if (virTestRun("Parsing a VPD resource with an invalid keyword ", testVirPCIVPDParseFullVPDSkipInvalidKeywords, NULL) < 0) ret =3D -1; --=20 2.32.0 From nobody Tue May 7 05:46:11 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 216.205.24.124 as permitted sender) client-ip=216.205.24.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of redhat.com designates 216.205.24.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=canonical.com Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by mx.zohomail.com with SMTPS id 1635533864524910.0044253857587; Fri, 29 Oct 2021 11:57:44 -0700 (PDT) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-265-cbrrQOu8OoeIcd5B4Lw_hA-1; Fri, 29 Oct 2021 14:57:39 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 9BDB3100CC93; Fri, 29 Oct 2021 18:57:32 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 7B6865BAF0; Fri, 29 Oct 2021 18:57:32 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 6F39C1806D03; Fri, 29 Oct 2021 18:57:30 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 19TIvTZL006392 for ; Fri, 29 Oct 2021 14:57:29 -0400 Received: by smtp.corp.redhat.com (Postfix) id 03F8C2026D67; Fri, 29 Oct 2021 18:57:29 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast04.extmail.prod.ext.rdu2.redhat.com [10.11.55.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id F27BF2026D65 for ; Fri, 29 Oct 2021 18:57:26 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [207.211.31.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id EA4F71066680 for ; Fri, 29 Oct 2021 18:57:25 +0000 (UTC) Received: from smtp-relay-internal-0.canonical.com (smtp-relay-internal-0.canonical.com [185.125.188.122]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-291-1JZO4nLHMN-5HgWI6IfWBg-1; Fri, 29 Oct 2021 14:57:23 -0400 Received: from mail-lj1-f200.google.com (mail-lj1-f200.google.com [209.85.208.200]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id D3EB73F1A9 for ; Fri, 29 Oct 2021 18:57:22 +0000 (UTC) Received: by mail-lj1-f200.google.com with SMTP id b8-20020a05651c028800b00211cc108922so3371623ljo.15 for ; Fri, 29 Oct 2021 11:57:22 -0700 (PDT) Received: from ws.lan.d-node.is ([95.165.29.203]) by smtp.gmail.com with ESMTPSA id a28sm663983ljd.65.2021.10.29.11.57.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 Oct 2021 11:57:21 -0700 (PDT) X-MC-Unique: cbrrQOu8OoeIcd5B4Lw_hA-1 X-MC-Unique: 1JZO4nLHMN-5HgWI6IfWBg-1 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=q+gU4dt+PBBe5EhruxfyU+PQvSq6pBBYpgXCVeypYuc=; b=GKJfBuesDYCcbb1H+t15pDN0vjgv8GVb1jUL3kfeeSgtasCjnsm7MVoAGkDe4XPpEu fw+7aculxF4yk1B9qgFJAXS6vHyJUmFTMjEggaq1S+dA4qxAAGW2ey27DA/iRMJyZJdn L3Tsd3dPf23IeYfxsrwTbcfWvfuyQ9BgtZU0atlUBkPRS6jNxQLrbo2CvjnhPV6zq6dM jDbQYKxMoTmU7UjmfK5BuhvNdlSJPUePGfL1R3lRYPDqPctnxs4FEoJjl/7pFOyRwNsR YTjAoyzBgfWU+mBoyiqpZVyYJywaxbm3ygZACKdx6JnpuudpiXaJFYdrkHee/L3YYcDV NmtA== X-Gm-Message-State: AOAM531HpXAe0YLj1XO5kf9HbBpgbGh+hRUm1ghcnPwhbrPn3zTdLdJ1 Ng4AhNaT6uLLZmBvoORjYJcchHn78WZIE5yj+e/tm8TNKob0+jRUko4OpVeOy1ILs0JfCn6LHsM mS/SZmXC9tpwULx6qbrTaOUFWL960Ni4CfQ== X-Received: by 2002:a05:6512:3d88:: with SMTP id k8mr11723450lfv.272.1635533842226; Fri, 29 Oct 2021 11:57:22 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy8OFzw123Lyaf6RmEyNtdRayIBzwJQ+XItsFscd9CxDBbxgOHHeD0vfl5dz8veok6PC8WQ/Q== X-Received: by 2002:a05:6512:3d88:: with SMTP id k8mr11723437lfv.272.1635533842050; Fri, 29 Oct 2021 11:57:22 -0700 (PDT) From: Dmitrii Shcherbakov To: libvir-list@redhat.com, dmitrii.shcherbakov@canonical.com Subject: [libvirt PATCH v2 3/3] PCI VPD: Fix a wrong return code in a test case Date: Fri, 29 Oct 2021 21:57:18 +0300 Message-Id: <20211029185718.338025-4-dmitrii.shcherbakov@canonical.com> In-Reply-To: <20211029185718.338025-1-dmitrii.shcherbakov@canonical.com> References: <20211029185718.338025-1-dmitrii.shcherbakov@canonical.com> MIME-Version: 1.0 X-Mimecast-Impersonation-Protect: Policy=CLT - Impersonation Protection Definition; Similar Internal Domain=false; Similar Monitored External Domain=false; Custom External Domain=false; Mimecast External Domain=false; Newly Observed Domain=false; Internal User Name=false; Custom Display Name List=false; Reply-to Address Mismatch=false; Targeted Threat Dictionary=false; Mimecast Threat Dictionary=false; Custom Threat Dictionary=false X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-MIME-Autoconverted: from quoted-printable to 8bit by lists01.pubmisc.prod.ext.phx2.redhat.com id 19TIvTZL006392 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1635533866297100003 Content-Type: text/plain; charset="utf-8" The test case should return -1, not 0 in case a valid resource could not be parsed successfully but the ret value is initialized to 0. Signed-off-by: Dmitrii Shcherbakov Tested-by: Daniel Henrique Barboza --- tests/virpcivpdtest.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/virpcivpdtest.c b/tests/virpcivpdtest.c index b7bc86d922..a9405f9427 100644 --- a/tests/virpcivpdtest.c +++ b/tests/virpcivpdtest.c @@ -537,7 +537,6 @@ testVirPCIVPDParseFullVPD(const void *opaque G_GNUC_UNU= SED) { int fd =3D -1; size_t dataLen =3D 0; - int ret =3D 0; =20 g_autoptr(virPCIVPDResource) res =3D NULL; /* Note: Custom fields are supposed to be freed by the resource cleanu= p code. */ @@ -558,7 +557,7 @@ testVirPCIVPDParseFullVPD(const void *opaque G_GNUC_UNU= SED) if (!res) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", "The resource pointer is NULL after parsing which i= s unexpected"); - return ret; + return -1; } =20 if (!res->ro) { @@ -596,7 +595,7 @@ testVirPCIVPDParseFullVPD(const void *opaque G_GNUC_UNU= SED) return -1; =20 custom =3D NULL; - return ret; + return 0; } =20 static int --=20 2.32.0