Campagne de recherche de bugs
Choisissez une expérience qui peut exposer une nouvelle garantie violée, puis dépensez du calcul en fonction de ce que l'expérience observe réellement. Gardez les coûts de découverte, de reproduction et de triage visibles. La vitesse est un facteur de performance listé à côté de « La couverture de code doit croître avec le temps » et de la résolution des problèmes bloquants, et une cible utile « doit avoir une bonne couverture dans le code qu'elle teste » ; le nombre d'exécutions seul n'établit pas une portée utile (Intégration OSS-Fuzz, Couverture, Performance ClusterFuzz, Facteurs de performance).
Établir la capacité actuelle
Lisez la révision cible réelle, la build activée, les producteurs de harnais et les corps d'assertion. Enregistrez quelles entrées, états initiaux, opérations, effets, ordonnancements, échecs et configurations chaque piste existante peut exercer et observer. Inspectez les exclusions et les cas rejetés. Utilisez les outils de couverture ou d'atteignabilité uniquement là où leur build/runtime documentée s'applique ; Fuzz Introspector documente des rapports « Pour les projets écrits en C/C++, Python et Java », chacun avec ses propres outils de build, ce n'est donc pas un backend universel (Fuzz Introspector, aperçu et Différences dans les outils de build). Pour un projet JavaScript ou TypeScript, lisez l'inventaire des pistes JS.
Considérez une capacité comme existante lorsque l'implémentation inspectée la fournit. Pour une cible utilisant déjà la génération de programmes valides, la comparaison de résultats entre moteurs et les historiques de transactions, ajouter les mêmes mécanismes sous de nouveaux noms n'est pas l'avancée proposée. Choisissez plutôt une interaction ou une observation non couverte : le dbsqlfuzz de SQLite « mute à la fois l'entrée SQL et le fichier de base de données en même temps » et a trouvé des fautes « manquées par les fuzzers précédents », un précédent concret pour rechercher des dimensions ensemble. C'est « un testeur de fuzz propriétaire » : empruntez le mécanisme, pas un outil public supposé (Test SQLite, §2 et §4.1.3).
Rendre un candidat exécutable
Décrivez le candidat dans la note d'expérience existante du projet ; n'introduisez pas de service ou de schéma obligatoire. Gardez ces décisions ensemble, avec des chemins de preuve. OSS-Fuzz demande qu'une cible « fasse au moins quelques progrès » lors d'un court lancement local, et la reproduction nécessite la build qui correspond au rapport (Intégration OSS-Fuzz, Cible de Fuzz, reproduction, Construire l'image et les fuzzers) :
- Producteur et écart : point d'entrée réel plus espace d'échec omis par la ligne de base.
- Garantie et oracle : contrat régissant, observation exécutable et résultats légaux/non supportés/non concluants.
- Recherche : valeurs/états/opérations générés et tout ordonnancement, faute ou choix de configuration contrôlés.
- Pilote : enveloppe de temps/travailleur/ressource autorisée, matériel de rejeu et preuve qui justifiera l'allocation suivante.
Concevez des observations avant de multiplier les charges de travail. Les objets traçables d'Elle révèlent des dépendances que les écrasements ordinaires cachent, car les écritures aveugles dans un registre « détruisent l'historique ». Son inférence a également des limites explicites : le vérificateur est correct et « s'approche de la garantie d'exhaustivité », et « Notre approche ignore les prédicats et ne traite que des objets individuels ». Un générateur qui produit plus d'historiques non informatifs ne répare pas ces limites (Elle, §§3, 4.3 et 9). Utilisez correctness-oracles pour le contrat général et un spécialiste en dessous pour son modèle particulier.
| Dimension ou observation manquante | Spécialiste pertinent |
|---|---|
| Objets API dépendants et séquences d'opérations légales | stateful-property-testing |
| États atteignables du navigateur ou de l'interface React sans modèle d'opération, avec oracles par état et rejeu de chemin | ui-state-exploration |
| Programmes valides à l'exécution avec état/effets requis | semantic-program-generation |
| Comparaison d'exécution indépendante ou relation justifiée entre exécutions | semantic-differential-testing, metamorphic-testing |
| Mécanismes d'instrumentation/recherche ou matériel de recherche conservé | coverage-guided-fuzzing, corpus-evolution |
| Diagnostics d'accès mémoire ou choix d'ordonnancement contrôlés | native-memory-instrumentation, race-detection-campaigns, schedule-exploration |
| Garanties d'objet concurrent ou de transaction | linearizability-checking, transactional-history-testing |
| Fautes de déploiement, environnement contrôlé ou limites de récupération | distributed-fault-testing, deterministic-simulation, crash-consistency-testing |
| Contraintes de chemin dures ou invariants bornés | symbolic-concolic-execution, bounded-model-checking |
| Croissance des ressources, progression, interactions de build ou précision numérique | resource-complexity-testing, liveness-testing, configuration-differential-testing, numerical-oracles |
Le tableau achemine les responsabilités de ce pack ; il n'établit pas qu'un outil nommé prend en charge la cible. Lisez uniquement le spécialiste sélectionné et ses références applicables. Utilisez harness-sensitivity pour obtenir la preuve qu'un nouvel oracle atteint et rejette des violations représentatives, de préférence via des régressions ou des contrôles existants ; le test de mutation de SQLite « vérifie que la suite de tests attrape la mutation » (Test SQLite, §7.6). Maintenez cela proportionnel à l'expérience, pas un cycle d'approbation récurrent.
Allouer à partir des preuves du pilote
Exécutez dans l'enveloppe autorisée. Vérifiez si le code cible et la propriété visée sont exercés ; distinguez les chemins indisponibles des chemins atteignables que la mutation n'a pas résolus. Fuzz Introspector compare le « potentiel d'atteignabilité statique » de chaque fuzzer à la couverture dynamique pour cette distinction. Modifiez l'expérience lorsqu'un producteur manquant, un prérequis sémantique ou une observation est le facteur limitant (Fuzz Introspector, aperçu). Pour les diagnostics, lisez diagnostic du pilote.
Étendez une piste informative lorsque ses preuves justifient plus de recherche. Comparez les pistes complémentaires lorsque leurs mécanismes de recherche diffèrent ; AFL++ dit « Pour chaque fuzzer secondaire, il doit y avoir une variation » (Profondeur AFL++, §3.c Utilisation de plusieurs cœurs). Utilisez le temps réel, les travailleurs et les limites de ressources, pas une durée ou un nombre de cœurs universels. Conservez les indicateurs d'exécution dans le spécialiste ; le délai d'attente par entrée, la durée de la campagne et les limites de mémoire sont des contrôles différents (Options libFuzzer 23.1.0).
Conservez les compteurs bruts pour les évaluations de propriété et la portée sémantique/code, les candidats bruts et les résultats reproduits, les doublons et les inconnus, et le coût de configuration/exécution/réduction/triage. Ne les réduisez pas en un score de productivité inventé. Lorsque des affirmations comparatives sont importantes, utilisez des conditions appariées et des essais répétés avec variabilité ; FuzzBench rapporte « le nombre d'essais, la moyenne, la médiane, l'écart » type et la « distribution des couvertures atteintes » plutôt qu'un seul lancement chanceux (Rapport FuzzBench, Résumé par benchmark).
Conservez les entrées originales, l'état de départ, la source/build/configuration, l'instrumentation, les sorties brutes et les choix de rejeu avant de résumer. Un cas de test OSS-Fuzz « contient les octets qui ont été fournis à la » cible, et certains bugs « ne sont reproductibles qu'en mode 32 bits ou qu'en mode 64 bits » sous le sanitizer rapporté ; une graine seule n'est pas cet artefact complet (Reproduction OSS-Fuzz, Bugs de cible de fuzz et Construire l'image et les fuzzers). Acheminez les candidats vers failure-reduction et evidence-based-triage ; laissez les résultats non fiables ou non résolus visibles plutôt que de les compter ou de les rejeter silencieusement. ClusterFuzz filtre sur la fiabilité de la reproduction et conserve des statistiques « sur la fréquence à laquelle les problèmes se produisent, et dans quelles conditions » (Triage ClusterFuzz, Filtrage des cas de test et Statistiques de crash).
Terminer la décision d'allocation
Enregistrez continuer, changer de dimension, reproduire/réduire/trier, ou arrêter, avec la raison observée et l'espace restant. Un plateau motive un diagnostic ; il ne prouve ni la correction ni qu'un autre outil aidera. Conservez zéro résultat comme un résultat borné. Une file d'attente de candidats non traités peut justifier de dépenser la prochaine tranche sur des preuves plutôt que sur la génération. Pour les cibles libFuzzer ou AFL guidées par la couverture, ClusterFuzz conseille que lorsqu'une cible trouve de nombreux nouveaux crashes, « les corriger est probablement plus important que d'analyser les performances » (Performance ClusterFuzz, Quand analyser les performances d'une cible de fuzz).
Retournez la garantie testée, le budget réel, le comportement atteint, les chemins de preuve, les résultats classifiés et la décision suivante. Décrivez les effets visibles par l'utilisateur là où ils sont établis ; gardez une cause possible séparée d'une violation démontrée. Pour un exemple d'allocation et d'enregistrement, lisez exemple de campagne ; pour les raccourcis trompeurs, lisez erreurs courantes.
L'invocation préserve le scope et les règles d'exécution existants de l'utilisateur. Elle n'autorise pas en soi les modifications de cible, les installations, les dépenses cloud, l'injection de fautes en production ou la publication externe.