From nobody Sat Nov 23 18:03:47 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 1724084959616442.35191878971; Mon, 19 Aug 2024 09:29:19 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 8E80C167; Mon, 19 Aug 2024 12:29:18 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 82EC61656; Mon, 19 Aug 2024 12:20:45 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 419B916F1; Mon, 19 Aug 2024 12:20:39 -0400 (EDT) Received: from mail-lj1-f173.google.com (mail-lj1-f173.google.com [209.85.208.173]) (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 141A215F6 for ; Mon, 19 Aug 2024 12:20:06 -0400 (EDT) Received: by mail-lj1-f173.google.com with SMTP id 38308e7fff4ca-2f189a2a7f8so46113281fa.2 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.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Aug 2024 09:20:03 -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=1724084404; x=1724689204; 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=FKD7hqnqLY5k6DiUCOER6txYcP8d6H+JUruQucXc450=; b=iptReZvHAvjViMcGT/+xwF32bJgRqbOXCh9k0xec0qOUYtwClCvIkbBH6naiysYoxZ Pnk+oiYsDJTnPTc/naEk+quR7RyZ6xfDDUXSGQANx7CnOPhrXbfdez5xfgKm44ST0QQh Alb+J5rJ1/krOdHTIMqlYZYldD5sjwHqYQ/zKVNbyaLYEM/WOQAepIZi1LG/CI0bK1Du XZ79mYMus9UiJLMaIKBiZiLyxq13eKD8gAcY/AU2ULhMPf1ahZq4+Uvf3qO/cHhILAZ+ foqdpB1SjzSk+xw0Jzc5Acd5169KGq+biGU/V4G+Eyyjk/nRs4lEZu9JYeNPjrwvQFkr Q+AQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724084404; x=1724689204; 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=FKD7hqnqLY5k6DiUCOER6txYcP8d6H+JUruQucXc450=; b=dovRn8kVHqG+Up7aFJslj+qD80/HpYWqPnd6pWP+xNX48iSskXaoYP9rmYzY1nPitq QSsEOkLLY+wCpkeF7qaAG1qlDzhuOixBd8Avj7n8zztEPuz5DqbQPSSQh4+1kOrO4yGf eoXvE1DMGFbwLSuLmpqu3K+0UcS/jdL82ZD7kP49h2/ZqaVgHvoYHIA6Vaez2MwB9MFp mFW5UIOqjnKlGPy8tzIU3x1Aa1O+eaSyTxKZX/1V7Qo37oiihR0A9AyQ5ItTNJU6twMk vvpCyufR6RI2qmV3siZumCmakYzBFRWz/2ocZAk5dTm8wRd930dxTtVjKgVxVIuzb2R0 q/MA== X-Gm-Message-State: AOJu0YwDbtlpfwvtXBmb88clMaKbvv9Y8Q57sQlXXay1uPQTWkRyIKP4 D0MXZk7UOzVyaaxbHG8RJh4hQNKhptW5w4SonB+jT3I0Vqr242J/hlo+Pw== X-Google-Smtp-Source: AGHT+IEvwr5jkfeiPonLKyu+wIM8WDGhPljBVbE+OA+jFjJhciYztgkpy2pEChvssG4F926klQ8VeQ== X-Received: by 2002:a2e:9c86:0:b0:2ef:216c:c97 with SMTP id 38308e7fff4ca-2f3be59b7eemr72539661fa.19.1724084403903; Mon, 19 Aug 2024 09:20:03 -0700 (PDT) From: Rayhan Faizel To: devel@lists.libvirt.org Subject: [PATCH 10/14] fuzz: Implement CH XML domain fuzzer Date: Mon, 19 Aug 2024 21:39:48 +0530 Message-Id: <20240819160952.351383-11-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: BZTH7JUEFHTNM4KB5FO47PSN4DQFCTKB X-Message-ID-Hash: BZTH7JUEFHTNM4KB5FO47PSN4DQFCTKB 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: 1724084961148116600 Content-Type: text/plain; charset="utf-8" This patch implements the harness for the Cloud-Hypervisor driver to fuzz XML parsing and XML-to-JSON generation including virCHMonitorBuildVMJson and virCHMonitorBuildNetJson. Signed-off-by: Rayhan Faizel --- src/ch/ch_monitor.c | 2 +- src/ch/ch_monitor.h | 3 + tests/fuzz/ch_xml_domain_fuzz.cc | 157 +++++++++++++++++++++++++++++++ tests/fuzz/meson.build | 17 ++++ tests/fuzz/proto_to_xml.cc | 18 ++++ tests/fuzz/proto_to_xml.h | 2 + 6 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 tests/fuzz/ch_xml_domain_fuzz.cc diff --git a/src/ch/ch_monitor.c b/src/ch/ch_monitor.c index 3e49902791..a10dd9f03d 100644 --- a/src/ch/ch_monitor.c +++ b/src/ch/ch_monitor.c @@ -423,7 +423,7 @@ virCHMonitorBuildDevicesJson(virJSONValue *content, return 0; } =20 -static int +int virCHMonitorBuildVMJson(virCHDriver *driver, virDomainDef *vmdef, char **jsonstr) { diff --git a/src/ch/ch_monitor.h b/src/ch/ch_monitor.h index b35f5ea027..aec4a06de8 100644 --- a/src/ch/ch_monitor.h +++ b/src/ch/ch_monitor.h @@ -133,3 +133,6 @@ virCHMonitorBuildNetJson(virDomainNetDef *netdef, int virCHMonitorBuildRestoreJson(virDomainDef *vmdef, const char *from, char **jsonstr); +int +virCHMonitorBuildVMJson(virCHDriver *driver, virDomainDef *vmdef, + char **jsonstr); diff --git a/tests/fuzz/ch_xml_domain_fuzz.cc b/tests/fuzz/ch_xml_domain_fu= zz.cc new file mode 100644 index 0000000000..6733f55378 --- /dev/null +++ b/tests/fuzz/ch_xml_domain_fuzz.cc @@ -0,0 +1,157 @@ +/* + * ch_xml_domain_fuzz.cc: Cloud-Hypervisor 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 +#include "ch/ch_conf.h" +#include "ch/ch_monitor.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; +uint64_t net =3D 0; +uint64_t net_success =3D 0; + +bool enable_xml_dump =3D false; +bool enable_xml_format =3D false; + +extern std::string emulator; + +static void +fuzzXMLToCommandLine(virCHDriver *driver, + const char *xml_string) +{ + virDomainDef *def =3D NULL; + g_autofree char *formatted_xml =3D NULL; + g_autofree char *json_str =3D NULL; + size_t i; + + parse_pass++; + if (!(def =3D virDomainDefParseString(xml_string, driver->xmlopt, NULL, + VIR_DOMAIN_DEF_PARSE_INACTIVE))) + goto cleanup; + + if (enable_xml_format) { + format_pass++; + if (!(formatted_xml =3D virDomainDefFormat(def, driver->xmlopt, + VIR_DOMAIN_DEF_FORMAT_SEC= URE))) + goto cleanup; + } + + command_line_pass++; + + if (virCHMonitorBuildVMJson(driver, def, &json_str) < 0) + goto cleanup; + success++; + + for (i =3D 0; i < def->nnets; i++) { + net++; + if (virCHMonitorBuildNetJson(def->nets[i], i, &json_str) =3D=3D 0) + net_success++; + } + + cleanup: + virDomainDefFree(def); +} + + +DEFINE_PROTO_FUZZER(const libvirt::MainObj &message) +{ + static virCHDriver *driver; + static bool initialized =3D false; + + 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"= ); + + std::string xml =3D ""; + + + /* + * One-time setup of CH driver. Re-running them in every + * iteration incurs a significant penalty to the speed of the fuzzer. + */ + if (!initialized) { + FUZZ_COMMON_INIT(); + + driver =3D g_new0(virCHDriver, 1); + + if (!(driver->caps =3D virCHDriverCapsInit())) { + printf("Unable to initialize driver capabilities\n"); + exit(EXIT_FAILURE); + } + + virCapsGuest *guest =3D driver->caps->guests[0]; + + /* Add KVM and HYPERV capabilities */ + virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_KVM, + NULL, NULL, 0, NULL); + + virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_HYPERV, + NULL, NULL, 0, NULL); + + if (!(driver->xmlopt =3D chDomainXMLConfInit(driver))) { + printf("Unable to initialize driver XMLOPT\n"); + exit(EXIT_FAILURE); + } + + emulator =3D "/usr/bin/cloud-hypervisor"; + + /* 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; + } + + convertProtoToCHXMLDomain(message, xml); + + if (enable_xml_dump) + printf("%s\n", xml.c_str()); + + fuzzXMLToCommandLine(driver, xml.c_str()); + + if (parse_pass % 1000 =3D=3D 0) + printf("[FUZZ METRICS] Parse: %lu, Format: %lu, Cmdline: %lu, Succ= ess: %lu, Network: %lu, Network Success: %lu\n", + parse_pass, format_pass, command_line_pass, success, net, n= et_success); + +} diff --git a/tests/fuzz/meson.build b/tests/fuzz/meson.build index 9579f56749..bb27c2843d 100644 --- a/tests/fuzz/meson.build +++ b/tests/fuzz/meson.build @@ -57,6 +57,23 @@ if conf.has('WITH_QEMU') ] endif =20 +if conf.has('WITH_CH') + fuzzer_src =3D [ + 'ch_xml_domain_fuzz.cc', + 'proto_to_xml.cc', + ] + + ch_libs =3D [ + ch_driver_impl, + test_utils_lib, + libvirt_lib, + ] + + xml_fuzzers +=3D [ + { 'name': 'ch_xml_domain_fuzz', 'src': [ fuzzer_src, xml_domain_proto_= src ], 'libs': ch_libs, 'macro': '-DXML_DOMAIN', 'deps': [ fuzz_autogen_xml= _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 36ad1028b1..40858e4779 100644 --- a/tests/fuzz/proto_to_xml.cc +++ b/tests/fuzz/proto_to_xml.cc @@ -216,6 +216,24 @@ void convertProtoToQEMUXMLDomain(const libvirt::MainOb= j &message, } =20 =20 +void convertProtoToCHXMLDomain(const libvirt::MainObj &message, + std::string &xml) +{ + xml =3D "\n" + " MyGuest\n" + " 4dea22b3-1d52-d8f3-2516-782e98ab3fa0\n" + " \n" + " hvm\n" + " hypervisor-fw\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 a87547a319..5c76772c5f 100644 --- a/tests/fuzz/proto_to_xml.h +++ b/tests/fuzz/proto_to_xml.h @@ -27,5 +27,7 @@ void convertProtoToQEMUXMLDomain(const libvirt::MainObj &message, std::string arch, std::string &xml); +void convertProtoToCHXMLDomain(const libvirt::MainObj &message, + std::string &xml); void convertProtoToXML(const libvirt::MainObj &message, std::string &xml); --=20 2.34.1