Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
gosentry — Chaîne d'outils Go orientée sécurité, axée sur des capacités de fuzzing de pointe. | Kitploit
Outils/GitHubGitHub/trailofbits/gosentry
Analyse StatiqueAnalyse Dynamique (Sandboxing)Analyse des VulnérabilitésAnalyse de CodeFuzzingDevSecOpsAnalyse de BinairesApprentissage et Éducation
GitHubtrailofbits/gosentry

gosentry

Chaîne d'outils Go orientée sécurité, axée sur des capacités de fuzzing de pointe.

Voir le dépôt
117335il y a 1 moisVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager
# gosentry

[![integration tests](https://github.com/trailofbits/gosentry/actions/workflows/go.yml/badge.svg?branch=master)](https://github.com/trailofbits/gosentry/actions/workflows/go.yml)

gosentry est un fork de la chaîne d'outils Go axé sur la sécurité, intégrant de nombreuses fonctionnalités pour des campagnes de fuzzing de pointe sur des codebases Go. Si vous utilisiez `go test -fuzz` auparavant, vous devriez utiliser gosentry comme remplacement. 
Il est fourni avec diverses améliorations de fuzzing et détecteurs de bogues qui ne sont pas présents nativement dans la chaîne d'outils Go. Voir TLDR ; ci-dessous. Vous pouvez également lire l'article de blog associé [ici](https://blog.trailofbits.com/2026/05/12/go-fuzzing-was-missing-half-the-toolkit.-we-forked-the-toolchain-to-fix-it./).

**TLDR (fonctionnalités et options)** :

- Fuzzer directement les entrées `struct` (aucun analyseur personnalisé n'est nécessaire). Ajoutez des graines avec `f.Add(Input{N: 7, S: "hi"})` puis `f.Fuzz(func(t *testing.T, in Input) { ... })`.
- Paniquer en cas de débordement d'entier et détecter les problèmes arithmétiques
- Fuzzer avec LibAFL pour des techniques de fuzzing de pointe comme la résolution de contraintes de chemin
- Générer/muter des entrées à partir d'une grammaire pour éviter les mutations inutiles. La mutation génère une opération mathématique valide comme `X + Y - Z` peut devenir `X / U + Z - 14` au lieu de `X + Yè - Z`
- Paniquer sur des fonctions sélectionnées (comme les enregistreurs d'erreurs critiques) et planter lorsqu'elle est appelée 
- Concentrer le fuzzer sur les lignes récemment modifiées ET sur les nouvelles couvertures pour cibler principalement les nouveaux commits
- Détecter les courses de données au moment du fuzzing
- Détecter les fuites Go au moment du fuzzing
- Détecter les exécutions bloquées avec des délais d'attente au moment du fuzzing
- Générer un rapport de couverture HTML à partir d'un corpus de campagne de fuzzing avec un seul CLI

## Table des matières

- [Compilation](#build)
  - [Fonctionnalité 1 : Fuzzing adapté aux structs (fuzzer des structs comme entrées)](#feature-1-struct-aware-fuzzing-fuzz-structs-as-inputs)
  - [Fonctionnalité 2 : Détection des débordements d'entiers et des problèmes de troncature](#feature-2-integer-overflow-and-truncation-issues-detection)
  - [Fonctionnalité 3 : Panique sur des fonctions sélectionnées](#feature-3-panic-on-selected-functions)
  - [Fonctionnalité 4 : Fuzzing de pointe avec LibAFL](#feature-4-libafl-state-of-the-art-fuzzing)
  - [Fonctionnalité 5 : Fuzzing orienté git-blame (expérimental)](#feature-5-git-blame-oriented-fuzzing-experimental)
  - [Fonctionnalité 6 : Détection des courses, des fuites de goroutines et des blocages au moment du fuzzing](#feature-6-detect-race-conditions-goroutine-leaks-and-hangs-at-fuzz-time)
  - [Fonctionnalité 7 : Fuzzing basé sur une grammaire (Nautilus)](#feature-7-grammar-based-fuzzing-nautilus)
  - [Fonctionnalité 8 : Générer des rapports de couverture de fuzzing à partir d'une campagne](#feature-8-generate-go-coverage-reports-from-fuzzing-campaign)
- [Trophées](#trophies)
- [Crédits](#credits)

## Compilation```bash
cd src && ./make.bash # Produces `../bin/go`. See `GOFLAGS` below.
```
> [!TIP]
> Documentation contributeur :  consultez `docs/gosentry/index.md` pour une carte du code, une boucle de développement recommandée, les points d'entrée CI et les scripts de benchmark.
> Ce fork utilise l'application GitHub Pull pour ouvrir et fusionner automatiquement les PR de `golang/go:master` vers `master`, garantissant que nous ne restons jamais en retard sur les dernières mises à jour de la chaîne d'outils Go.

## Fonctionnalité 1 : Fuzzing conscient des structures (fuzzer des structures en entrée)

#### Aperçu

Le fuzzing natif de Go (`go test -fuzz=...`) ne prend en charge qu'un petit ensemble de types scalaires comme paramètres de fuzzing (`[]byte`, `string`, nombres, ...). Dans gosentry, vous pouvez également fuzzer des **types composites** construits à partir de ces scalaires : structures, tableaux, slices et pointeurs.
Cela est utile lorsque votre code prend naturellement des entrées structurées et que vous ne souhaitez pas créer un encodeur/décodeur personnalisé uniquement pour amorcer et muter le corpus. 
Voir `test/gosentry/examples/multiargs` et `test/gosentry/examples/composite` pour des exemples.

#### Exemple simple```go
type Input struct {
	Data []byte
	S    string
	N    int
	OK   bool
}

func FuzzStructInput(f *testing.F) {
	// Seed the initial corpus with a Go struct (gosentry feature).
	f.Add(Input{Data: []byte("A"), S: "B", N: 7, OK: true})

	f.Fuzz(func(t *testing.T, in Input) {
		if in.OK && in.N == 1337 && in.S == "BOOMMOOB" && bytes.Equal(in.Data, []byte("A")) {
			t.Fatalf("boom")
		}
	})
}
```
<details>
<summary><strong>Comment fonctionnent les seeds de type struct (<code>f.Add</code>) et le fuzzing de structs (le lien ainsi créé)</strong></summary>

Le fuzzer natif de Go ne peut pas fuzzer une valeur `struct` directement (il ne sait muter qu'une petite liste de types scalaires). gosentry ajoute une petite couche de liaison : lorsque votre cible de fuzzing utilise des types composites (comme `Input`), gosentry fuzz un simple `[]byte` en coulisses. À chaque exécution, il **décode** ces octets dans votre struct (champ par champ, récursivement pour les slices/tableaux/pointeurs), puis appelle votre rappel `f.Fuzz` avec la valeur décodée. Le même **encodage** est utilisé pour les seeds, de sorte qu'un `f.Add(Input{...})` devient une entrée de corpus `[]byte` encodée que le fuzzer peut réutiliser et muter comme n'importe quelle autre seed.

Les fuzzers (y compris LibAFL) mutent des octets bruts, nous voulons donc un décodeur capable de transformer **n'importe quelle** tranche d'octets en une valeur de struct « quelconque » et de continuer. JSON/`gob` rejetteraient la plupart des entrées aléatoires (mauvais pour la couverture) et ne rempliraient pas non plus les champs non exportés, alors que le fuzzing bénéficie souvent de la rupture des invariants. Ce format personnalisé est petit, rapide, déterministe et tolérant aux données malformées.

Sous le capot, cela utilise le propre format binaire simple de gosentry (pas `gob`, pas JSON). Le code se trouve dans `src/testing/libafl.go` :
- Encodage : `libaflMarshalInputs` / `libaflAppendValue`
- Décodage : `libaflUnmarshalArgs` / `libaflDecodeValue`

Règles d'encodage (niveau haut) :
- `bool` : 1 octet (`0` ou `1`)
- Entiers : octets en little-endian (`int`/`uint` font 8 octets)
- Flottants : bits IEEE-754 en little-endian (`float32` = 4 octets, `float64` = 8 octets)
- `string` : `uvarint(len)` puis les octets bruts de la chaîne
- `[]byte` : `uvarint(len)` puis les octets bruts
- Autres slices : `uvarint(len)` puis chaque élément encodé
- Structures : champs encodés dans l'ordre de déclaration
- Pointeurs : 1 octet (`0` = nil, `1` = présent) puis la valeur pointée
 
 
</details>

## Fonctionnalité 2 : Détection des problèmes de débordement et de troncature d'entiers

#### Aperçu

Ce travail s'inspire du [go-panikint](https://github.com/trailofbits/go-panikint) développé précédemment. Il ajoute la détection des débordements/sous-dépassements pour les opérations arithmétiques sur les entiers et (optionnellement) la détection des troncatures de type pour les conversions d'entiers. Lorsqu'un débordement ou une troncature est détecté, une panique avec un message d'erreur détaillé est déclenchée, incluant le type d'opération spécifique et les types d'entiers impliqués.

_Opérations arithmétiques_ : Gère l'addition `+`, la soustraction `-`, la multiplication `*` et la division `/` pour les entiers signés et non signés. Pour les entiers signés, couvre `int8`, `int16`, `int32`. Pour les entiers non signés, couvre `uint8`, `uint16`, `uint32`, `uint64`. Le cas de la division détecte spécifiquement la condition de débordement `MIN_INT / -1` pour les entiers signés. `int64` et `uintptr` ne sont pas vérifiés pour les opérations arithmétiques.

_Détection de troncature de type_ : Détecte les conversions de types d'entiers potentiellement avec perte. Couvre tous les types d'entiers : `int8`, `int16`, `int32`, `int64`, `uint8`, `uint16`, `uint32`, `uint64`. Exclut `uintptr` en raison d'une utilisation dépendante de la plateforme. Cette détection est désactivée par défaut.

La détection de débordement est activée par défaut. Pour la désactiver, ajoutez `GOFLAGS='-gcflags=-overflowdetect=false'` avant votre `./make.bash`. Vous pouvez également activer le vérificateur de problèmes de troncature avec : `-gcflags=-truncationdetect=true`

#### Comment cela fonctionne

Cette fonctionnalité modifie la génération SSA du compilateur afin que les opérations arithmétiques sur les entiers et les conversions d'entiers reçoivent des vérifications d'exécution supplémentaires qui appellent le runtime pour déclencher une panique avec un message d'erreur détaillé lorsqu'un bug est détecté. Les vérifications sont appliquées via un filtrage basé sur l'emplacement source, de sorte que le code utilisateur est instrumenté tandis que les fichiers de la bibliothèque standard et les dépendances (cache de modules et `vendor/`) sont ignorés.

Vous pouvez lire l'article de blog associé [**ici**](https://blog.trailofbits.com/2025/12/31/detect-gos-silent-arithmetic-bugs-with-go-panikint/).

#### Suppression des faux positifs

Ajoutez un marqueur sur la même ligne que l'opération ou sur la ligne immédiatement au-dessus pour supprimer un signalement spécifique :

- Débordement/sous-dépassement : `overflow_false_positive`
- Troncature : `truncation_false_positive`

Exemple :

```go
``````go
// overflow_false_positive
intentionalOverflow := a + b
// truncation_false_positive
x := uint8(big)
sum2 := a + b // overflow_false_positive
x2 := uint8(big) // truncation_false_positive
```
Parfois, cela peut ne pas fonctionner, car Go met la fonction en ligne. Si `// overflow_false_positive` ne suffit pas, ajoutez `//go:noinline` avant la signature de votre fonction.

## Fonctionnalité 3 : Panique sur des fonctions sélectionnées

Lors du fuzzing de cibles, nous pouvons être intéressés par le déclenchement d'une panique lorsque certaines fonctions sont appelées. Par exemple, certains logiciels peuvent émettre des messages `log.error` au lieu de paniquer, même si ces conditions indiquent souvent des états que les chercheurs en sécurité souhaiteraient détecter pendant le fuzzing.
Cependant, ces erreurs sont généralement gérées en interne (par exemple, via des mécanismes de nouvelle tentative ou de pause, ou en imprimant des messages dans les journaux), ce qui les rend largement invisibles pour les fuzzers. L'objectif de cette fonctionnalité est de résoudre ce problème.

#### Comment utiliser

Compilez gosentry, puis utilisez l'option `--panic-on`.```bash
./bin/go test -fuzz=FuzzHarness --use-libafl --focus-on-new-code=false --catch-races=false --catch-leaks=false --panic-on="test_go_panicon.(*Logger).Warning,test_go_panicon.(*Logger).Error"
```
L'exemple ci-dessus provoquerait un panic lorsque `(*Logger).Warning` ou `(*Logger).Error` est appelé (liste séparée par des virgules).

<details>
<summary><strong>Comment fonctionne la fonctionnalité de panic sur les fonctions sélectionnées</strong></summary>```text
┌───────────────────────────────────────────────────────────────────────────┐
│ 1) gosentry `go test`                                                      │
│    - parses + validates `-panic-on=...` against packages being built      │
│    - forwards patterns to the compiler via `-panic-on-call=...`           │
└───────────────┬───────────────────────────────────────────────────────────┘
                v
┌───────────────────────────────────────────────────────────────────────────┐
│ 2) `cmd/compile`                                                          │
│    - prevents inlining of matching calls so the call stays visible        │
│    - SSA pass inserts a call to `runtime.panicOnCall(...)`                │
└───────────────┬───────────────────────────────────────────────────────────┘
                v
┌───────────────────────────────────────────────────────────────────────────┐
│ 3) `runtime.panicOnCall`                                                  │
│    - panics with: "panic-on-call: func-name"                              │
└───────────────────────────────────────────────────────────────────────────┘
```
En pratique, cela fait que tout site d'appel correspondant se comporte comme un crash/panic pour les fuzzers (notez que seuls les sites d'appel statiques peuvent être interceptés).
</details>

## Fonctionnalité 4 : fuzzing de pointe avec LibAFL
 
LibAFL est *bien* plus performant que le fuzzer Go traditionnel. Lors du fuzzing (`go test -fuzz=...`), gosentry utilise [LibAFL](https://github.com/AFLplusplus/LibAFL) **par défaut** (runner dans `golibafl/`).
 
Note de stabilité : en mode LibAFL, gosentry force `GODEBUG=updatemaxprocs=0` (désactive les mises à jour automatiques de GOMAXPROCS par le runtime) pour éviter un crash intermittent du CI Linux ("sync: inconsistent mutex state"). Les détails se trouvent dans `misc/gosentry/USE_LIBAFL.md`.
 
Lorsque vous utilisez LibAFL (par défaut), vous devez explicitement choisir d'activer ou non la planification git-aware : `--focus-on-new-code=true|false`. Plus de documentation dans [ce fichier Markdown.](https://github.com/trailofbits/gosentry/blob/master/misc/gosentry/USE_LIBAFL.md)
Vous pouvez également passer un fichier de configuration JSONC optionnel pour LibAFL (incluant les options de fuzzing par grammaire), voir [ici.](https://github.com/trailofbits/gosentry/blob/master/misc/gosentry/libafl.config.jsonc)
Avec `"stop_all_fuzzers_on_panic": false`, LibAFL enregistre chaque crash et redémarre son client pour continuer le fuzzing.```bash
./bin/go test -fuzz=FuzzHarness --focus-on-new-code=false --catch-races=false --catch-leaks=false --libafl-config=path/to/libafl.jsonc # optional --libafl-config
```
Utilisez `-fuzztime=1m` pour arrêter une campagne LibAFL après une minute.

La génération de rapports de couverture à partir d'un corpus de campagne LibAFL est documentée dans [Feature 8](#feature-8-generate-go-coverage-reports-from-fuzzing-campaign).

Le fuzzing basé sur une grammaire (Nautilus) est documenté dans [Feature 7](#feature-7-grammar-based-fuzzing-nautilus).

<details>
<summary><strong>Comment Go et LibAFL sont connectés</strong></summary>```text
┌───────────────────────────────────────────────────────────────────────────┐
│ 1) gosentry `go test`                                                      │
│    - captures  `testing.F.Fuzz(...)` callback                             │
│    - generates  extra source file: `_libaflmain.go`                       │
└───────────────┬───────────────────────────────────────────────────────────┘
                v
┌───────────────────────────────────────────────────────────────────────────┐
│ 2) Generated bridge: `_libaflmain.go`                                     │
│    - provides libFuzzer-style C ABI entrypoints:                          │
│        LLVMFuzzerInitialize                                               │
│        LLVMFuzzerTestOneInput                                             │
│    - adapts bytes -> Go types -> calls the captured fuzz callback         │
└───────────────┬───────────────────────────────────────────────────────────┘ 
                v
┌───────────────────────────────────────────────────────────────────────────┐
│ 3) `libharness.a` (static archive on disk) contains:                      │
│      - compiled objects for all test package (+ dependencies)             │
│      - generated `_testmain.go` + `_libaflmain.go`                        │
│      - LLVMFuzzerInitialize                                               │
│      - LLVMFuzzerTestOneInput                                             │
└───────────────┬───────────────────────────────────────────────────────────┘
                v
┌───────────────────────────────────────────────────────────────────────────┐
│ 4) `golibafl/` (Rust + LibAFL)                                            │
│    env: HARNESS_LIB=/path/to/libharness.a                                 │
│    fuzz loop: mutate input -> LLVMFuzzerTestOneInput(data) -> observe     │
└───────────────────────────────────────────────────────────────────────────┘
```
En mode `--use-libafl`, gosentry compile `libharness.a` et le runner Rust `golibafl` le pilote en cours de processus via les points d'entrée libFuzzer. Remarque : `HARNESS_LIB` peut pointer vers n'importe quel nom d'archive de harness (par exemple `libharness_race.a` utilisé par `--catch-races`).
</details>

<details>
<summary><strong>Comment fonctionne l'instrumentation de couverture (LibAFL + cible Go)</strong></summary>

En mode `--use-libafl`, gosentry compile le harness Go avec l'instrumentation de couverture activée. Cela ajoute de petits compteurs au code qui changent lorsque différentes parties de votre programme s'exécutent. Lorsque le harness démarre dans `golibafl`, le runtime Go expose ces compteurs à LibAFL. LibAFL les lit après chaque entrée pour voir quel code a été exécuté, et utilise cette couverture pour guider les mutations suivantes.

</details>



##### Limitations
Parlons de la motivation derrière l'utilisation de LibAFL. Le fuzzing avec `go test -fuzz` est _loin_ derrière les techniques de fuzzing de pointe. Un bon exemple en est CMPLOG/Redqueen d'AFL++. Ces fonctionnalités permettent aux fuzzers de résoudre certaines contraintes. Prenons l'extrait suivant```go
if input == "IMARANDOMSTRINGJUSTCMPLOGMEMAN" {
	panic("this string is illegal")
}
```
SOTA fuzzers comme AFL++ ou LibAFL détecteraient la panique instantanément dans ce cas. Cependant, le fuzzer natif de Go ne le ferait pas. C'est une énorme lacune qui restreint considérablement l'exploration de la couverture.

Le benchmark ci-dessous montre ces limites. Notez que ces benchmarks peuvent être **reproduits** et améliorés via le [dépôt gosentry-bench-libafl](https://github.com/kevin-valerio/gosentry-bench-libafl/tree/main).

##### Benchmark 1:

Le graphique ci-dessous montre l'évolution du nombre de lignes couvertes lors du fuzzing de l'[UUID](https://github.com/google/uuid) de Google avec LibAFL par rapport au fuzzer natif de Go.
![BENCH1](https://assets.kitploit.com/production/public/readmes/41918/7b1ea005996846c9ee4d7c0d42fee26731050d10b6b21d59c551e4b1b956923e.png "BENCH1")

##### Benchmark 2:

Le graphique ci-dessous montre l'évolution du nombre de lignes couvertes lors du fuzzing de [go-ethereum](https://github.com/ethereum/go-ethereum) avec LibAFL par rapport au fuzzer natif de Go.
![BENCH2](https://assets.kitploit.com/production/public/readmes/41918/61aab8540ab8d339307854de6737a405056c3c8ad83a822df40f74e362b93021.png "BENCH2")



#### Exemple
Vous pouvez le tester sur certains harnais de fuzzing dans `test/gosentry/examples/`.```bash
cd test/gosentry/examples/reverse
../../../../bin/go test -fuzz=FuzzReverse --focus-on-new-code=false --catch-races=false --catch-leaks=false
```
Arrêtez la campagne de fuzzing avec Ctrl+C.

##### Répertoire de sortie LibAFL (identité de la campagne / réutilisation du corpus)

gosentry stocke l'état de la campagne LibAFL (corpus, crashes, etc.) sous la racine du cache de fuzzing de Go (approximativement `$(go env GOCACHE)/fuzz`), dans un répertoire déterministe dérivé du **même package + même cible de fuzzing** (et de la même racine de projet).

Cela signifie que l'arrêt (Ctrl+C) puis le redémarrage de la même campagne de fuzzing reprendra, par défaut, à partir du corpus `queue/` LibAFL précédent.

Le chemin est affiché à la fin de l'exécution :```text
libafl output dir: /full/path/to/.../fuzz/<pkg import path>/libafl/<project>/<harness>
```
Notes :
- `<harness>` est le nom de la cible de fuzzing lorsque `-fuzz` est un identifiant simple comme `FuzzXxx` (ou `^FuzzXxx$`), sinon c’est `pattern-<hash>`.
- La génération de couverture (`--generate-coverage`) utilise la même règle pour trouver le corpus `queue/` approprié, elle doit donc être exécutée depuis le même package avec le même `-fuzz=...`.

## Fonctionnalité 5 : Fuzzing orienté git blame (expérimental)

#### Aperçu

Le fuzzing guidé par la couverture est excellent pour explorer de nouveaux chemins, mais il considère tout le code couvert comme également intéressant. Lorsque vous fuzzez de grandes bases de code, vous pouvez vouloir orienter le fuzzer vers le code récemment modifié, là où les régressions et les bogues sont plus susceptibles d’être introduits. En mode LibAFL, gosentry peut utiliser `git blame` pour privilégier les entrées qui exécutent des lignes récemment modifiées (tout en gardant le guidage par couverture comme signal principal).

Ce travail est basé sur des travaux antérieurs de [LibAFL-git-aware](https://github.com/kevin-valerio/LibAFL-git-aware). Tous les détails techniques approfondis y sont documentés.

#### Comment l’utiliser

Activez la planification git-aware avec `--focus-on-new-code=true` :```bash
./bin/go test -fuzz=FuzzHarness --use-libafl --focus-on-new-code=true --catch-races=false --catch-leaks=false
```
Ce mode nécessite `git` (pour exécuter `git blame`) et `go tool addr2line` pour mapper les compteurs de couverture aux `file:line` de la source.

<details>
<summary><strong>Comment fonctionne le fuzzing orienté git-blame</strong></summary>```text
┌───────────────────────────────────────────────────────────────────────────┐
│ 1) gosentry `go test -fuzz`                                                │
│    - builds `libharness.a` (contains `go.o` + `.go.fuzzcntrs`)            │
│    - runs `golibafl` with `GOLIBAFL_FOCUS_ON_NEW_CODE=1`                  │
└───────────────┬───────────────────────────────────────────────────────────┘
                v
┌───────────────────────────────────────────────────────────────────────────┐
│ 2) `golibafl` generates a cached "git recency map"                         │
│    - maps coverage counters -> (file:line) via `go tool addr2line`        │
│    - runs `git blame` to get a timestamp per line                         │
│    - stores timestamps in `git_recency_map.bin`                           │
└───────────────┬───────────────────────────────────────────────────────────┘
                v
┌───────────────────────────────────────────────────────────────────────────┐
│ 3) LibAFL scheduler uses the recency map                                  │
│    - coverage decides what enters the corpus                              │
│    - among the corpus, prioritize inputs that hit newer lines             │
└───────────────────────────────────────────────────────────────────────────┘
```
</details>

<details>
<summary><strong>Comment gosentry construit <code>git_recency_map.bin</code></strong></summary>

`.go.fuzzcntrs` est la section de l'éditeur de liens qui contient les **compteurs de couverture 8 bits** de style libFuzzer de Go (activés par `-gcflags=all=-d=libfuzzer`) ; chaque octet indique « combien de fois ce point instrumenté a été atteint ». Lorsque `--focus-on-new-code=true`, `golibafl` génère `git_recency_map.bin` de la manière suivante :
  1. Extraire `go.o` de `libharness.a`.
  2. Lire la taille de la section `.go.fuzzcntrs` pour obtenir le nombre de compteurs `N`.
  3. Analyser les relocations de `.text` qui référencent les symboles `.go.fuzzcntrs` pour retrouver l'adresse de chaque index de compteur.
  4. Résoudre chaque adresse en `file:line` à l'aide de `go tool addr2line`.
  5. Exécuter `git blame --line-porcelain` pour obtenir `committer-time` par ligne.
  6. Écrire `git_recency_map.bin` sous la forme `u64 head_time` + `u64 N` + `N * u64 timestamps` (little-endian). Les entrées non mappées utilisent l'horodatage `0`.

</details>

<details>
<summary><strong>Benchmark 1 (go-ethereum / geth) : baseline vs git-aware</strong></summary>

Exécuté avec `misc/gosentry/bench_focus_on_new_code_geth.sh --trials 5 --warmup 600 --timeout 200`.```text
  gitaware_5: crash (7122ms)
baseline results:
  trial 1: crash (107747ms)
  trial 2: crash (146415ms)
  trial 3: crash (37902ms)
  trial 4: crash (154034ms)
  trial 5: timeout (200000ms)
baseline crashes: 4/5 (timeouts=1, errors=0)
baseline median (capped to timeout): 146.415s

git-aware results:
  trial 1: timeout (200000ms)
  trial 2: crash (87432ms)
  trial 3: crash (61733ms)
  trial 4: crash (157540ms)
  trial 5: crash (7122ms)
git-aware crashes: 4/5 (timeouts=1, errors=0)
git-aware median (capped to timeout): 87.432s
```
</details>

## Fonctionnalité 6 : Détecter les courses de données, les fuites de goroutines et les blocages (timeouts) au moment du fuzzing

##### Détection des blocages confirmés (timeouts LibAFL)

Lors du fuzzing avec LibAFL, une exécution de harness peut **expirer** (par exemple à cause d'un deadlock / de goroutines bloquées en attente, ou d'un chemin extrêmement lent).

Pour réduire les faux positifs, gosentry considère un timeout comme un candidat au blocage et le confirme en rejouant l'entrée ayant expiré plusieurs fois avec un timeout plus grand. En cas de blocage confirmé, gosentry écrit l'entrée dans `<libafl output dir>/hangs/` et arrête la campagne de fuzzing (il la traite comme un bug/crash).

Avant de se terminer, `golibafl` tente de minimiser l'entrée qui provoque le crash/blocage (au mieux ; les blocages sont plafonnés à ~60 s au total).

Remarque : la confirmation de blocage s'exécute également lors de l'importation/génération initiale du corpus, de sorte que les cibles qui expirent sur chaque entrée peuvent encore être détectées de manière déterministe.

Ceci est configuré via `--libafl-config` :
- `catch_hangs` (défaut : `true`)
- `hang_timeout_ms` (défaut : `10000`)
- `hang_confirm_runs` (défaut : `3`)

##### Détection des courses de données (`--catch-races`)

gosentry peut exécuter une boucle de rejeu séparée `-race` qui surveille le répertoire `queue/` de LibAFL et rejoue les seeds nouvellement découvertes avec `GORACE=halt_on_error=1`.

La boucle de rejeu construit une archive de harness `-race` séparée, réservée au rejeu (sans instrumentation de couverture de fuzzing).

Lorsqu'une course de données est détectée pendant le rejeu, gosentry affiche le rapport complet du détecteur de courses avant le résumé `catch-races:` et la commande de reproduction.

Remarque : le détecteur de courses de Go ne détecte les courses de données qu'**à l'intérieur d'une seule exécution de harness** (courses entre goroutines du même processus accédant à la même mémoire sans synchronisation appropriée). `--catch-races` manquera les courses si la seed ne déclenche pas la concurrence conflictuelle, et il ne détecte pas les courses entre processus.

<details>
<summary><strong>Comment fonctionne le mode de détection de courses de données</strong></summary>

Ce mode démarre un petit moniteur à l'intérieur de `go test` (même processus parent), et il s'exécute pendant toute la campagne de fuzzing.

- Quand : avant que le processus principal de fuzzing LibAFL ne soit démarré, gosentry construit le harness de rejeu + le runner.
- Surveillance : avant que le fuzzing ne démarre, gosentry enregistre l'état initial du contenu de `<libafl output dir>/queue/` dans un ensemble `seen`. Une goroutine interroge ensuite `<libafl output dir>/queue/` toutes les ~1 s et ne rejoue que les seeds nouvellement créées (ignore les fichiers cachés et `*.metadata`).```text
Legend: output/... = <libafl output dir>/...

┌───────────────────────────────────────────────────────────────────────────┐
│ 1) Main LibAFL fuzzing run                                                 │
│    - `golibafl` writes new seeds to `output/queue/`                        │
└───────────────┬───────────────────────────────────────────────────────────┘
                v
┌───────────────────────────────────────────────────────────────────────────┐
│ 2) `--catch-races` sidecar setup                                           │
│    - builds replay harness: `libharness_race.a` (`go test -race ...`)      │
│    - builds replay runner: `golibafl-race` (linked against race harness)   │
└───────────────┬───────────────────────────────────────────────────────────┘
                v
```

---

[Read more](https://github.com/trailofbits/gosentry)
Télécharger l’outil