From nobody Sat Nov 23 17:40:30 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=gmail.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1724084989417927.8633713928589; Mon, 19 Aug 2024 09:29:49 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 618C015F8; Mon, 19 Aug 2024 12:29:48 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 6B01716F1; Mon, 19 Aug 2024 12:20:47 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 906D115AB; Mon, 19 Aug 2024 12:20:41 -0400 (EDT) Received: from mail-ed1-f51.google.com (mail-ed1-f51.google.com [209.85.208.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id AFB0D15DB for ; Mon, 19 Aug 2024 12:20:06 -0400 (EDT) Received: by mail-ed1-f51.google.com with SMTP id 4fb4d7f45d1cf-5bed72ff443so3435199a12.1 for ; Mon, 19 Aug 2024 09:20:06 -0700 (PDT) Received: from localhost.localdomain ([37.186.51.21]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5bebbde4964sm5738298a12.24.2024.08.19.09.20.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Aug 2024 09:20:04 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.6 required=5.0 tests=DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1724084405; x=1724689205; darn=lists.libvirt.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=XRpE58r9w4OK8gP3DtqkI40B6Fz9zSRb+2imLuhC4JU=; b=KphR0HTEfMCPeG3zX3pAWhDm0NEI5xtYXeB/baPcgmsnm/yvnGew4/4aDD2OHij+Oz RTa3kMeyEdIF/a/2oAfYsyw7+waAs/D7pgUcWJ4w0dv4ba0Fi3QIcjpuwQBppZ+rNsjn zemBnui/qHwF1WVx9dAQq/SIoZRQQHbzvi4Tb86DvQwBbbWBkEOz7jl8FFJprBm2kaha MxS2K5tymKI1OBT5wuuhTsI2NRgn2K1hsSZ3sISZIY7UXMxnDrg8YaTGHNRSyF4EgkLi +0U6yWKCbbDB3Xc9VhUpmoJx7/OEI7koz/33Ns3mMi+gdIvARBwoBaFpT1vfsSaaKk0P TBEQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724084405; x=1724689205; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=XRpE58r9w4OK8gP3DtqkI40B6Fz9zSRb+2imLuhC4JU=; b=JUiuIi3RYIFJU1HRuVFuMCuRAnqLrreHQfyoWXhLFULZstw+HWsWFx2Ru9jm/Ekhp0 4PCdYyGydlE5U5qSUiDntVRYMbyePoJdNNH3/+gg5nj5+y+V1yi0XLRbZ3zF/qMIcujV 4H/IVkFXNqM5OPm0RdrbvUxVTtSYALyTPLw1NBH8PGhp/gw+kx21ufiwJZGRopg5j4Kj /hlKaw8CwvALOLLaKyl3XslFOhT/FwICxQ8baJ28PiXpqmkaedwFNbjGiPwKFlpPitsv y2qBQWVpPvSzEIpP8Y86FlkaEHim0R5CC1Im5Je3A3suzWHiFFYuY9uy9kpk0iTYGzSN CuSg== X-Gm-Message-State: AOJu0YyKDa49Uo+2vbEZw7dWC9dfkmbyYdggVBAyz4XJiOdV5jOQB+Lu YN8nwJZ7fFgcLbZz6S/BCsYOEvcRCwSLEjE/l55WjMEbPr5bKRU3r9T8Sg== X-Google-Smtp-Source: AGHT+IHt2Gb8E0hrjoJSeZgJ+YTGUjff9VVm8QG//gc9vaOMY2oAjrYIIE6EpkI2uBqVEPaKWvQ39Q== X-Received: by 2002:a05:6402:35cc:b0:5be:f101:9297 with SMTP id 4fb4d7f45d1cf-5bef10199d9mr3559389a12.2.1724084405228; Mon, 19 Aug 2024 09:20:05 -0700 (PDT) From: Rayhan Faizel To: devel@lists.libvirt.org Subject: [PATCH 11/14] fuzz: Implement VMX XML domain fuzzer Date: Mon, 19 Aug 2024 21:39:49 +0530 Message-Id: <20240819160952.351383-12-rayhan.faizel@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240819160952.351383-1-rayhan.faizel@gmail.com> References: <20240819160952.351383-1-rayhan.faizel@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Message-ID-Hash: Z2IYTCIQD27SZ3W4R6K4KBYBMGAY43IR X-Message-ID-Hash: Z2IYTCIQD27SZ3W4R6K4KBYBMGAY43IR X-MailFrom: rayhan.faizel@gmail.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: Rayhan Faizel X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1724084991253116600 Content-Type: text/plain; charset="utf-8" This patch adds the harness for the VMX driver to fuzz XML parsing and VMX config generation. VMX config generation is done with a hardcoded version of 13. Signed-off-by: Rayhan Faizel --- tests/fuzz/meson.build | 16 +++ tests/fuzz/proto_to_xml.cc | 18 +++ tests/fuzz/proto_to_xml.h | 3 + tests/fuzz/vmx_xml_domain_fuzz.cc | 208 ++++++++++++++++++++++++++++++ 4 files changed, 245 insertions(+) create mode 100644 tests/fuzz/vmx_xml_domain_fuzz.cc diff --git a/tests/fuzz/meson.build b/tests/fuzz/meson.build index bb27c2843d..88b5fe103c 100644 --- a/tests/fuzz/meson.build +++ b/tests/fuzz/meson.build @@ -74,6 +74,22 @@ if conf.has('WITH_CH') ] endif =20 +if conf.has('WITH_VMX') + fuzzer_src =3D [ + 'vmx_xml_domain_fuzz.cc', + 'proto_to_xml.cc', + ] + + vmx_libs =3D [ + test_utils_lib, + libvirt_lib, + ] + + xml_fuzzers +=3D [ + { 'name': 'vmx_xml_domain_fuzz', 'src': [ fuzzer_src, xml_domain_proto= _src ], 'libs': vmx_libs, 'macro': '-DXML_DOMAIN', 'deps': [ fuzz_autogen_x= ml_domain_dep ] }, + ] +endif + foreach fuzzer: xml_fuzzers xml_domain_fuzz =3D executable(fuzzer['name'], fuzzer['src'], diff --git a/tests/fuzz/proto_to_xml.cc b/tests/fuzz/proto_to_xml.cc index 40858e4779..983256bcae 100644 --- a/tests/fuzz/proto_to_xml.cc +++ b/tests/fuzz/proto_to_xml.cc @@ -234,6 +234,24 @@ void convertProtoToCHXMLDomain(const libvirt::MainObj = &message, } =20 =20 +void convertProtoToVMXXMLDomain(const libvirt::MainObj &message, + std::string arch, + std::string &xml) +{ + xml =3D "\n" + " MyGuest\n" + " 4dea22b3-1d52-d8f3-2516-782e98ab3fa0\n" + " \n" + " hvm\n" + " \n" + " 4096\n"; + + convertProtoToXMLInternal(message, xml, true); + + xml +=3D "\n"; +} + + void convertProtoToXML(const libvirt::MainObj &message, std::string &xml) { diff --git a/tests/fuzz/proto_to_xml.h b/tests/fuzz/proto_to_xml.h index 5c76772c5f..89e6726611 100644 --- a/tests/fuzz/proto_to_xml.h +++ b/tests/fuzz/proto_to_xml.h @@ -29,5 +29,8 @@ void convertProtoToQEMUXMLDomain(const libvirt::MainObj &= message, std::string &xml); void convertProtoToCHXMLDomain(const libvirt::MainObj &message, std::string &xml); +void convertProtoToVMXXMLDomain(const libvirt::MainObj &message, + std::string arch, + std::string &xml); void convertProtoToXML(const libvirt::MainObj &message, std::string &xml); diff --git a/tests/fuzz/vmx_xml_domain_fuzz.cc b/tests/fuzz/vmx_xml_domain_= fuzz.cc new file mode 100644 index 0000000000..69859551bd --- /dev/null +++ b/tests/fuzz/vmx_xml_domain_fuzz.cc @@ -0,0 +1,208 @@ +/* + * vmx_xml_domain_fuzz.cc: VMX domain fuzzing harness + * + * Copyright (C) 2024 Rayhan Faizel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#include +#include "proto_header_common.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +extern "C" { +#include "testutils.h" +#include "internal.h" +#include "viralloc.h" +#include "vmx/vmx.h" +} + +#include "port/protobuf.h" +#include "proto_to_xml.h" +#include "src/libfuzzer/libfuzzer_macro.h" + +uint64_t parse_pass =3D 0; +uint64_t format_pass =3D 0; +uint64_t command_line_pass =3D 0; +uint64_t success =3D 0; + +bool enable_xml_dump =3D false; +bool enable_xml_format =3D false; + +static void +fuzzXMLToCommandLine(virVMXContext *ctx, + virDomainXMLOption *xmlopt, + const char *xml_string) +{ + virDomainDef *def =3D NULL; + g_autofree char *formatted_xml =3D NULL; + g_autofree char *formatted_config =3D NULL; + + parse_pass++; + if (!(def =3D virDomainDefParseString(xml_string, xmlopt, NULL, + VIR_DOMAIN_DEF_PARSE_INACTIVE))) + goto cleanup; + + if (enable_xml_format) { + format_pass++; + if (!(formatted_xml =3D virDomainDefFormat(def, xmlopt, + VIR_DOMAIN_DEF_FORMAT_SEC= URE))) + goto cleanup; + } + + command_line_pass++; + + if (!(formatted_config =3D virVMXFormatConfig(ctx, xmlopt, def, 13))) { + goto cleanup; + } + + success++; + + cleanup: + + virDomainDefFree(def); +} + + +virCaps *fuzzCapsInit() { + virCapsGuest *guest =3D NULL; + virCaps *caps =3D NULL; + + caps =3D virCapabilitiesNew(VIR_ARCH_I686, true, true); + + if (caps =3D=3D NULL) + return NULL; + + virCapabilitiesAddHostMigrateTransport(caps, "esx"); + + /* i686 guest */ + guest =3D virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM, + VIR_ARCH_I686, + NULL, NULL, 0, NULL); + + virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_VMWARE, + NULL, NULL, 0, NULL); + + /* x86_64 guest */ + guest =3D virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM, + VIR_ARCH_X86_64, + NULL, NULL, 0, NULL); + + virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_VMWARE, + NULL, NULL, 0, NULL); + + return caps; +} + + +static char * +fuzzFormatVMXFileName(const char *src G_GNUC_UNUSED, + void *opaque G_GNUC_UNUSED) +{ + return g_strdup("/vmfs/volumes/test1/test2"); +} + + +static int +fuzzAutodetectSCSIControllerModel(virDomainDiskDef *def G_GNUC_UNUSED, + int *model, void *opaque G_GNUC_UNUSED) +{ + *model =3D VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC; + + return 0; +} + + +DEFINE_PROTO_FUZZER(const libvirt::MainObj &message) +{ + static virVMXContext ctx; + static virDomainXMLOption *xmlopt =3D NULL; + static virCaps *caps; + + static bool initialized =3D false; + + static const char *arch_env =3D g_getenv("LPM_FUZZ_ARCH"); + static const char *dump_xml_env =3D g_getenv("LPM_XML_DUMP_INPUT"); + static const char *format_xml_env =3D g_getenv("LPM_XML_FORMAT_ENABLE"= ); + + static std::string arch =3D ""; + + std::string xml =3D ""; + + /* + * One-time setup of VMX driver. Re-running them in every + * iteration incurs a significant penalty to the speed of the fuzzer. + */ + if (!initialized) { + FUZZ_COMMON_INIT(); + + caps =3D fuzzCapsInit(); + + if (caps =3D=3D NULL) { + exit(EXIT_FAILURE); + } + + if (arch_env) { + arch =3D arch_env; + } else { + arch =3D "x86_64"; + } + + if (!(arch =3D=3D "x86_64" || arch =3D=3D "i686")) { + printf("Unsupported architecture: %s\n", arch.c_str()); + exit(EXIT_FAILURE); + } + + if (!(xmlopt =3D virVMXDomainXMLConfInit(caps))) + exit(EXIT_FAILURE); + + ctx.opaque =3D NULL; + ctx.parseFileName =3D NULL; + ctx.formatFileName =3D fuzzFormatVMXFileName; + ctx.autodetectSCSIControllerModel =3D fuzzAutodetectSCSIController= Model; + ctx.datacenterPath =3D NULL; + + /* Enable printing of XML to stdout (useful for debugging crashes)= */ + if (dump_xml_env && STREQ(dump_xml_env, "YES")) + enable_xml_dump =3D true; + + /* Enable fuzzing of XML formatting */ + if (format_xml_env && STREQ(format_xml_env, "YES")) + enable_xml_format =3D true; + + initialized =3D true; + } + + convertProtoToVMXXMLDomain(message, arch, xml); + + if (enable_xml_dump) + printf("%s\n", xml.c_str()); + + fuzzXMLToCommandLine(&ctx, xmlopt, xml.c_str()); + + if (parse_pass % 1000 =3D=3D 0) + printf("[FUZZ METRICS] Parse: %lu, Format: %lu, Cmdline: %lu, Succ= ess: %lu\n", + parse_pass, format_pass, command_line_pass, success); + +} --=20 2.34.1