From nobody Wed May 15 15:26:08 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=yandex-team.ru ARC-Seal: i=1; a=rsa-sha256; t=1638722862; cv=none; d=zohomail.com; s=zohoarc; b=gTfDvdaNr8bDhhoyrxrGpqnF/WhXuA5GFiy35BPnUPAz6oGAsuJMi6wx6j668JOKCRopcJU0he76g6cqyOGbiwIEzOchoabWJ6hzvir9jLAD0tqkDOdxXeMdEJbWa/PNcMkq/7MI8T+44Z+iqH39p2uRnAQUNItwqMpxuORwuYY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1638722862; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:To; bh=qjlwsxvSac4hOSK78fwlfqcok5dspyYJkM5S0bFOvnA=; b=CV76Z6MCEZ9HffJK4xLEqNotmSZSr+DvmnTEsd2382Mop6RTnQOIYmv29ad8RsCbXU/YiuGcb5OdrLZ0KN4enNrh09Czd+r/nRX2AVo9XO1wrn1cEnEBNY+JSvGt8J2wn23iXUBptRMrtjStNQV5TkhodCLtKxRB2Lbk9MeSOQo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1638722862456334.15157923975744; Sun, 5 Dec 2021 08:47:42 -0800 (PST) Received: from localhost ([::1]:39928 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mtuft-0005ZZ-8L for importer@patchew.org; Sun, 05 Dec 2021 11:47:41 -0500 Received: from eggs.gnu.org ([209.51.188.92]:48186) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mtuDM-00024z-On for qemu-devel@nongnu.org; Sun, 05 Dec 2021 11:18:12 -0500 Received: from forwardcorp1o.mail.yandex.net ([95.108.205.193]:60746) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mtuDI-0001CK-CS for qemu-devel@nongnu.org; Sun, 05 Dec 2021 11:18:10 -0500 Received: from vla1-fdfb804fb3f3.qloud-c.yandex.net (vla1-fdfb804fb3f3.qloud-c.yandex.net [IPv6:2a02:6b8:c0d:3199:0:640:fdfb:804f]) by forwardcorp1o.mail.yandex.net (Yandex) with ESMTP id 5D5922E0B0A; Sun, 5 Dec 2021 19:17:57 +0300 (MSK) Received: from vla1-81430ab5870b.qloud-c.yandex.net (vla1-81430ab5870b.qloud-c.yandex.net [2a02:6b8:c0d:35a1:0:640:8143:ab5]) by vla1-fdfb804fb3f3.qloud-c.yandex.net (mxbackcorp/Yandex) with ESMTP id Nc7ng97gqy-HuLGrnB8; Sun, 05 Dec 2021 19:17:57 +0300 Received: from localhost (dynamic-vpn.dhcp.yndx.net [2a02:6b8:b081:8024::1:6]) by vla1-81430ab5870b.qloud-c.yandex.net (smtpcorp/Yandex) with ESMTPSA id YbAz2Fa83K-HuP4HsVJ; Sun, 05 Dec 2021 19:17:56 +0300 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (Client certificate not present) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1638721077; bh=qjlwsxvSac4hOSK78fwlfqcok5dspyYJkM5S0bFOvnA=; h=Date:To:From:Subject:Message-ID:Cc; b=OTF58rpOskwwjq6Mc8WK5DSiAIaFnuQtzBUhbxodLQt6aqfmt5stSHsIaCjF/Q8P2 6/ErcoNvOWqYHHzrrlMOHiVDWp3j6kByhnXnIlqhkqWTdN0zZMkpu84tKGKrowoCRI a2zR3nNmcTUHxubH5PUToz28QHTA3s4IKFgEVF60= Authentication-Results: vla1-fdfb804fb3f3.qloud-c.yandex.net; dkim=pass header.i=@yandex-team.ru X-Yandex-Fwd: 2 Subject: [PATCH] fuzz: pass failures from child process into libfuzzer engine From: Konstantin Khlebnikov To: qemu-devel@nongnu.org Date: Sun, 05 Dec 2021 19:17:56 +0300 Message-ID: <163872107649.53117.6457962986798427964.stgit@dynamic-vpn.dhcp.yndx.net> User-Agent: StGit/1.4.dev11+gd5bef96 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=95.108.205.193; envelope-from=khlebnikov@yandex-team.ru; helo=forwardcorp1o.mail.yandex.net X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Sun, 05 Dec 2021 11:46:49 -0500 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexander Bulekov Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @yandex-team.ru) X-ZM-MESSAGEID: 1638722864449100001 Fuzzer is supposed to stop when first bug is found and report failure. Present fuzzers fork new child at each iteration to isolate side-effects. But child's exit code is ignored, i.e. libfuzzer does not see any crashes. Right now virtio-net fuzzer instantly falls on assert in iov_copy and dumps crash-*, but fuzzing continues and ends successfully if global timeout is set. Let's put required logic into helper function "fork_fuzzer_and_wait". Signed-off-by: Konstantin Khlebnikov --- tests/qtest/fuzz/fork_fuzz.c | 26 ++++++++++++++++++++++++++ tests/qtest/fuzz/fork_fuzz.h | 1 + tests/qtest/fuzz/generic_fuzz.c | 3 +-- tests/qtest/fuzz/i440fx_fuzz.c | 3 +-- tests/qtest/fuzz/virtio_blk_fuzz.c | 6 ++---- tests/qtest/fuzz/virtio_net_fuzz.c | 6 ++---- tests/qtest/fuzz/virtio_scsi_fuzz.c | 6 ++---- 7 files changed, 35 insertions(+), 16 deletions(-) diff --git a/tests/qtest/fuzz/fork_fuzz.c b/tests/qtest/fuzz/fork_fuzz.c index 6ffb2a7937..6e3a3867bf 100644 --- a/tests/qtest/fuzz/fork_fuzz.c +++ b/tests/qtest/fuzz/fork_fuzz.c @@ -38,4 +38,30 @@ void counter_shm_init(void) free(copy); } =20 +/* Returns true in child process */ +bool fork_fuzzer_and_wait(void) +{ + pid_t pid; + int wstatus; + + pid =3D fork(); + if (pid < 0) { + perror("fork"); + abort(); + } + + if (pid =3D=3D 0) { + return true; + } =20 + if (waitpid(pid, &wstatus, 0) < 0) { + perror("waitpid"); + abort(); + } + + if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) !=3D 0) { + abort(); + } + + return false; +} diff --git a/tests/qtest/fuzz/fork_fuzz.h b/tests/qtest/fuzz/fork_fuzz.h index 9ecb8b58ef..792e922731 100644 --- a/tests/qtest/fuzz/fork_fuzz.h +++ b/tests/qtest/fuzz/fork_fuzz.h @@ -18,6 +18,7 @@ extern uint8_t __FUZZ_COUNTERS_START; extern uint8_t __FUZZ_COUNTERS_END; =20 void counter_shm_init(void); +bool fork_fuzzer_and_wait(void); =20 #endif =20 diff --git a/tests/qtest/fuzz/generic_fuzz.c b/tests/qtest/fuzz/generic_fuz= z.c index dd7e25851c..f0e25b39ea 100644 --- a/tests/qtest/fuzz/generic_fuzz.c +++ b/tests/qtest/fuzz/generic_fuzz.c @@ -667,7 +667,7 @@ static void generic_fuzz(QTestState *s, const unsigned = char *Data, size_t Size) size_t cmd_len; uint8_t op; =20 - if (fork() =3D=3D 0) { + if (fork_fuzzer_and_wait()) { struct sigaction sact; struct itimerval timer; sigset_t set; @@ -723,7 +723,6 @@ static void generic_fuzz(QTestState *s, const unsigned = char *Data, size_t Size) _Exit(0); } else { flush_events(s); - wait(0); } } =20 diff --git a/tests/qtest/fuzz/i440fx_fuzz.c b/tests/qtest/fuzz/i440fx_fuzz.c index 86796bff2b..0b927f4b3a 100644 --- a/tests/qtest/fuzz/i440fx_fuzz.c +++ b/tests/qtest/fuzz/i440fx_fuzz.c @@ -147,12 +147,11 @@ static void i440fx_fuzz_qos(QTestState *s, =20 static void i440fx_fuzz_qos_fork(QTestState *s, const unsigned char *Data, size_t Size) { - if (fork() =3D=3D 0) { + if (fork_fuzzer_and_wait()) { i440fx_fuzz_qos(s, Data, Size); _Exit(0); } else { flush_events(s); - wait(NULL); } } =20 diff --git a/tests/qtest/fuzz/virtio_blk_fuzz.c b/tests/qtest/fuzz/virtio_b= lk_fuzz.c index 623a756fd4..9532dc1fa7 100644 --- a/tests/qtest/fuzz/virtio_blk_fuzz.c +++ b/tests/qtest/fuzz/virtio_blk_fuzz.c @@ -136,13 +136,12 @@ static void virtio_blk_fork_fuzz(QTestState *s, if (!queues) { queues =3D qvirtio_blk_init(blk->vdev, 0); } - if (fork() =3D=3D 0) { + if (fork_fuzzer_and_wait()) { virtio_blk_fuzz(s, queues, Data, Size); flush_events(s); _Exit(0); } else { flush_events(s); - wait(NULL); } } =20 @@ -152,7 +151,7 @@ static void virtio_blk_with_flag_fuzz(QTestState *s, QVirtioBlk *blk =3D fuzz_qos_obj; static QVirtioBlkQueues *queues; =20 - if (fork() =3D=3D 0) { + if (fork_fuzzer_and_wait()) { if (Size >=3D sizeof(uint64_t)) { queues =3D qvirtio_blk_init(blk->vdev, *(uint64_t *)Data); virtio_blk_fuzz(s, queues, @@ -162,7 +161,6 @@ static void virtio_blk_with_flag_fuzz(QTestState *s, _Exit(0); } else { flush_events(s); - wait(NULL); } } =20 diff --git a/tests/qtest/fuzz/virtio_net_fuzz.c b/tests/qtest/fuzz/virtio_n= et_fuzz.c index 0e873ab8e2..6b492ef9e7 100644 --- a/tests/qtest/fuzz/virtio_net_fuzz.c +++ b/tests/qtest/fuzz/virtio_net_fuzz.c @@ -118,26 +118,24 @@ static void virtio_net_fuzz_multi(QTestState *s, static void virtio_net_fork_fuzz(QTestState *s, const unsigned char *Data, size_t Size) { - if (fork() =3D=3D 0) { + if (fork_fuzzer_and_wait()) { virtio_net_fuzz_multi(s, Data, Size, false); flush_events(s); _Exit(0); } else { flush_events(s); - wait(NULL); } } =20 static void virtio_net_fork_fuzz_check_used(QTestState *s, const unsigned char *Data, size_t Size) { - if (fork() =3D=3D 0) { + if (fork_fuzzer_and_wait()) { virtio_net_fuzz_multi(s, Data, Size, true); flush_events(s); _Exit(0); } else { flush_events(s); - wait(NULL); } } =20 diff --git a/tests/qtest/fuzz/virtio_scsi_fuzz.c b/tests/qtest/fuzz/virtio_= scsi_fuzz.c index 6ff6fabe4a..c7eaf3242b 100644 --- a/tests/qtest/fuzz/virtio_scsi_fuzz.c +++ b/tests/qtest/fuzz/virtio_scsi_fuzz.c @@ -140,13 +140,12 @@ static void virtio_scsi_fork_fuzz(QTestState *s, if (!queues) { queues =3D qvirtio_scsi_init(scsi->vdev, 0); } - if (fork() =3D=3D 0) { + if (fork_fuzzer_and_wait()) { virtio_scsi_fuzz(s, queues, Data, Size); flush_events(s); _Exit(0); } else { flush_events(s); - wait(NULL); } } =20 @@ -156,7 +155,7 @@ static void virtio_scsi_with_flag_fuzz(QTestState *s, QVirtioSCSI *scsi =3D fuzz_qos_obj; static QVirtioSCSIQueues *queues; =20 - if (fork() =3D=3D 0) { + if (fork_fuzzer_and_wait()) { if (Size >=3D sizeof(uint64_t)) { queues =3D qvirtio_scsi_init(scsi->vdev, *(uint64_t *)Data); virtio_scsi_fuzz(s, queues, @@ -166,7 +165,6 @@ static void virtio_scsi_with_flag_fuzz(QTestState *s, _Exit(0); } else { flush_events(s); - wait(NULL); } } =20