diff options
| -rw-r--r-- | _content/doc/index.adoc | 11 | ||||
| -rw-r--r-- | _content/doc/security/fuzz/example.png | bin | 0 -> 53157 bytes | |||
| -rw-r--r-- | _content/doc/security/fuzz/index.adoc | 402 | ||||
| -rw-r--r-- | _content/doc/security/fuzz/technical.adoc | 84 | ||||
| -rw-r--r-- | _content/doc/tutorial/fuzz/index.adoc | 10 |
5 files changed, 499 insertions, 8 deletions
diff --git a/_content/doc/index.adoc b/_content/doc/index.adoc index 8255886..9bde86a 100644 --- a/_content/doc/index.adoc +++ b/_content/doc/index.adoc @@ -109,6 +109,11 @@ Sebuah tulisan yang harus dibaca bagi yang baru memprogram Go. Dokumen ini menggabungkan spesifikasi bahasa dan tur, yang mana keduanya sebaiknya dibaca terlebih dahulu. +[#faq] +=== link:/doc/faq/index.html[Tanya jawab^] + +Dokumen ini berisi jawaban dari pertanyaan yang sering diajukan tentang Go. + [#editors] === link:/doc/editors.html[Plugin untuk editor dan IDE^] @@ -127,10 +132,10 @@ permasalahan dalam program. Bila kode Anda menggunakan paket-paket eksternal, paket tersebut (yang didistribusikan sebagai module) menjadi dependensi. -[#faq] -=== link:/doc/faq/index.html[Tanya jawab^] +=== link:/doc/security/fuzz/[_Fuzzing_^] + +Dokumentasi untuk _fuzzing_ pada Go. -Dokumen ini berisi jawaban dari pertanyaan yang sering diajukan tentang Go. [#references] == Referensi diff --git a/_content/doc/security/fuzz/example.png b/_content/doc/security/fuzz/example.png Binary files differnew file mode 100644 index 0000000..b500603 --- /dev/null +++ b/_content/doc/security/fuzz/example.png diff --git a/_content/doc/security/fuzz/index.adoc b/_content/doc/security/fuzz/index.adoc new file mode 100644 index 0000000..b913b4f --- /dev/null +++ b/_content/doc/security/fuzz/index.adoc @@ -0,0 +1,402 @@ += Go _Fuzzing_ +:toc: +:sectanchors: + +Go mendukung _fuzzing_ pada perkakas baku sejak Go version 1.18. +Pengujian fuzz pada Go +https://google.github.io/oss-fuzz/getting-started/new-project-guide/go-lang/#native-go-fuzzing-support[didukung oleh OSS-Fuzz^]. + +*Cobalah link:/doc/tutorial/fuzz/[tutorial untuk _fuzzing_ pada Go^].* + +== Pendahuluan + +_Fuzzing_ adalah tipe pengujian otomatis yang secara terus menerus +memanipulasi input-input pada program untuk menemukan kecacatan. +_Fuzzing_ pada Go menggunakan panduan cakupan (_coverage guidance_) untuk +secara pintar menelusuri kode yang tengah di-_fuzz_ and melaporkan kegagalan +pada pengguna. +Secara ia dapat menemukan kasus-kasus yang terkadang tidak terpikirkan oleh +manusia, pengujian _fuzz_ dapat berguna untuk menemukan celah keamanan yang +dapat di-eksploitasi. + +Contoh berikut adalah sebuah +link:#glos-fuzz-test[fuzz tes], +menyoroti komponen-komponen utamanya. + +image::example.png["Contoh kode memperlihatkan fuzz tes, dengan target yang di fuzz. Sebelum target fuzz adalah penambahan sebuah corpus dengan f.Add, dan parameter-parameter dari target fuzz ditandai sebagai argumen-argumen dari fuzzing.", width=600, height=auto] + + +== Membuat fuzz tes + +[#requirements] +=== Kebutuhan + +Berikut aturan-aturan yang harus diikuti oleh fuzz tes. + +* Sebuah fuzz tes haruslah sebuah fungsi dengan nama seperti `FuzzXxx`, yang + menerima hanya `*testing.F`, dan tidak memiliki kembalian. +* Fuzz tes haruslah berada dalam berkas `\_test.go` supaya dapat dijalankan. +* Sebuah + link:#gloss-fuzz-target[target fuzz] + haruslah berupa pemanggilan method + https://pkg.go.dev/testing#F.Fuzz[`*testing.F`^] + yang menerima sebuah argumen `*testing.T` sebagai parameter pertama, + diikuti oleh argumen-argumen _fuzzing_. + Tidak ada nilai kembalian. +* Harus ada satu target fuzz per satu fuzz tes. +* Semua isi + link:#glos-seed-corpus[bibit _corpus_] + haruslah memiliki tipe yang identik dengan + link:#glos-fuzzing-arguments[argumen fuzzing], + dengan urutan yang sama. + Hal ini juga berlaku untuk pemanggilan + https://pkg.go.dev/testing#F.Add[`(*testing.F).Add`] + dan semua berkas _corpus_ dalam direktori `testdata/fuzz` dari fuzz tes. +* Argumen _fuzzing_ hanya dapat memiliki tipe-tipe berikut: +** `string`, `[]byte` +** `int`, `int8`, `int16`, `int32`/`rune`, `int64` +** `uint`, `uint8`/`byte`, `uint16`, `uint32`, `uint64` +** `float32`, `float64` +** `bool` + + +[#suggestions] +=== Saran-saran + +Berikut beberapa saran yang membantu Anda dalam fuzzing. + +* Target dari _fuzz_ haruslah cepat dan deterministik sehingga mesin + _fuzzing_ dapat bekerja secara efisien, sehingga kegagalan yang ditemukan + berikut cakupan kode dapat dengan mudah diulang. + +* Secara target _fuzz_ dipanggil dengan paralel antara beberapa _worker_ dan + dengan urutan yang tidak deterministik, kondisi dari target _fuzz_ + sebaiknya tidak disimpan sampai pemanggilan berakhir, dan perilaku dari + target _fuzz_ sebaiknya tidak bergantung pada kondisi global. + + +== Menjalankan fuzz tes + +Ada dua mode untuk menjalankan fuzz tes: sebagai unit tes (dengan `go +test`), atau dengan _fuzzing_ (`go test -fuzz=FuzzTestName`). + +Fuzz tes berjalan seperti unit tes. +Setiap +link:#glos-seed-corpus[isi bibit _corpus_] +akan diuji terhadap target fuzz, dan akan melaporkan bila ada kegagalan +sebelum tes selesai. + +Untuk mengaktifkan _fuzzing_, jalankan `go test` dengan opsi `-fuzz`, dengan +mengirim sebuah _regex_ dengan nama fuzz tes yang diinginkan. +Secara bawaan, semua tes di dalam paket tersebut akan dijalankan sebelum +fuzz tes berjalan. +Hal ini untuk memastikan fuzz tes tidak melaporkan isu-isu yang mungkin +ditemukan oleh unit tes yang telah ada. + +Ingatlah bahwa lamanya fuzz tes berjalan dapat ditentukan sendiri. +Fuzz tes dapat berjalan selamanya jika tidak menemukan kesalahan. +Nantinya akan ada dukungan untuk menjalankan fuzz tes menggunakan perkakas +seperti OSS-Fuzz, lihat +https://go.dev/issue/50192["isu #50192"^]. + +NOTE: _Fuzzing_ harus berjalan pada sistem yang mendukung instrumentasi +cakupan (saat ini AMD64 dan ARM64) supaya _corpus_ dapat terus berkembang +saat fuzz tes berjalan, dan lebih banyak kode yang tercakup saat _fuzzing_. + + +=== Keluaran perintah _fuzzing_ + +Saat _fuzzing_ berjalan, +link:#glos-fuzzing-engine[mesin _fuzzing_] +menghasilkan input-input yang baru dan mengirimnya ke target fuzz. +Secara bawaan, fuzz tes akan terus berjalan sampai menemukan +link:#glos-failing-input[input yang gagal], +atau bila user membatalkan tes (misalnya dengan CTRL^C). + +Keluaran dari perintah fuzz tes seperti berikut: + +---- +$ go test -fuzz FuzzFoo +fuzz: elapsed: 0s, gathering baseline coverage: 0/192 completed +fuzz: elapsed: 0s, gathering baseline coverage: 192/192 completed, now fuzzing with 8 workers +fuzz: elapsed: 3s, execs: 325017 (108336/sec), new interesting: 11 (total: 202) +fuzz: elapsed: 6s, execs: 680218 (118402/sec), new interesting: 12 (total: 203) +fuzz: elapsed: 9s, execs: 1039901 (119895/sec), new interesting: 19 (total: 210) +fuzz: elapsed: 12s, execs: 1386684 (115594/sec), new interesting: 21 (total: 212) +PASS +ok foo 12.692s +---- + +Baris pertama mengindikasikan bahwa "baseline coverage" (dasar cakupan) +dikumpulkan sebelum _fuzzing_ dimulai. + +Untuk mengumpulkan dasar cakupan, mesin _fuzzing_ mengeksekusi +link:#glos-seed-corpus[bibit _corpus_] +dan +link:#glos-generated-corpus[bangkitan _corpus_], +untuk memastikan bahwa tidak ada kesalahan yang terjadi dan untuk +mempelajari cakupan kode yang telah ditangani oleh _corpus_ yang sudah ada. + +Baris-baris selanjutnya menjelaskan eksekusi _fuzzing_: + +* _elapsed_: jumlah waktu yang telah berjalan sejak proses dimulai. +* _execs_: jumlah input yang telah dikirim ke target fuzz (dengan + rata-rata eksekusi/detik sejak baris sebelumnya) +* _new interesting_: jumlah input yang "menarik" yang telah ditambahkan ke + dalam bangkitan _corpus_ selama eksekusi _fuzzing_ (dengan total jumlah + _corpus_). + +Untuk sebuah input disebut "menarik", ia harus menambah cakupan kode +melewati jumlah yang dihasilkan oleh _corpus_ sebelumnya. +Sangat wajar bila jumlah input "menarik" tersebut meningkat dengan cepat +pada saat awal dan kemudian melambat, dengan sekali-kali meningkat saat +cabang kode yang baru ditemukan. + +Anda akan melihat jumlah "new interesting" semakin lama semakin naik saat +input-input di dalam _corpus_ menemukan baris-baris kode yang baru, yang +terkadang-kadang melonjak saat mesin _fuzzing_ menemukan jalur kode yang +baru. + +=== Input yang gagal + +Sebuah kegagalan bisa terjadi saat _fuzzing_ berjalan karena beberapa +hal: + +* _panic_ terjadi pada kode atau tes. +* Target fuzz memanggil `t.Fail`, baik secara langsung atau lewat method + seperti `t.Error` atau `t.Fatal`. +* Kegagalan yang tidak diharapkan terjadi, seperti `os.Exit` atau + _stack overflow_. +* Target fuzz butuh waktu lama untuk selesai. + Saat ini, tenggat waktu untuk sebuah eksekusi target fuzz yaitu 1 detik. + Target fuzz bisa gagal disebabkan karena _deadlock_ atau pengulangan tanpa + henti, atau dari kondisi yang tidak diharapkan dalam kode. + Karena inilah kenapa + link:#suggestions[target fuzz disarankan harus cepat]. + +Bila sebuah kegagalan terjadi, mesin _fuzzing_ akan mencoba me-minimalisasi +ukuran input dengan nilai yang masih bisa dibaca oleh manusia, namun masih +tetap menimbulkan kegagalan. +Untuk mengatur hal ini, lihat bagian +link:#custom-settings[pengaturan khusus]. + +Setelah minimalisasi selesai, pesan kegagalan akan ditulis, dan menampilkan +keluaran seperti berikut: + +---- + Failing input written to testdata/fuzz/FuzzFoo/a878c3134fe0404d44eb1e662e5d8d4a24beb05c3d68354903670ff65513ff49 + To re-run: + go test -run=FuzzFoo/a878c3134fe0404d44eb1e662e5d8d4a24beb05c3d68354903670ff65513ff49 +FAIL +exit status 1 +FAIL foo 0.839s +---- + +Mesin _fuzzing_ menulis +link:#glos-failing-input[input yang gagal] +ke bibit _corpus_ dari fuzz tes tersebut, dan nanti akan dijalankan secara +otomatis lewat `go test`, yang dipakai sebagai regresi tes saat kecacatan +tersebut telah diperbaiki. + +Langkah selanjutnya yaitu mendiagnosis permasalahan, memperbaiki kecacatan, +memverifikasi perbaikan dengan menjalankan `go test` kembali. + + +[#custom-settings] +=== Pengaturan khusus + +Pengaturan bawaan dari perintah `go` berjalan untuk kebanyakan kasus +dari _fuzzing_. +Pada umumnya, eksekusi _fuzzing_ berbentuk seperti berikut: + +---- +$ go test -fuzz={FuzzTestName} +---- + +Namun, perintah `go` menyediakan beberapa pengaturan untuk menjalankan +_fuzzing_. +Ini didokumentasikan dalam +https://pkg.go.dev/cmd/go[dokumentasi paket `cmd/go`^]. + +Beberapa pengaturan tersebut antara lain: + +* `-fuzztime`: jumlah waktu atau jumlah iterasi yang akan dieksekusi oleh + target fuzz sebelum keluar, nilai bakunya adalah selamanya. +* `-fuzzminimizetime`: waktu atau jumlah iterasi yang akan dieksekusi target + fuzz selama minimalisasi, nilai bakunya 60 detik. + Minimalisasi dapat dimatikan dengan `-fuzzminimizetime 0`. +* `-parallel`: jumlah proses _fuzzing_ yang berjalan, nilai bakunya yaitu + sama dengan nilai `$GOMAXPROCS`. + Saat ini, opsi `-cpu` saat _fuzzing_ tidak berpengaruh. + + +== Format berkas _corpus_ + +Berkas-berkas _corpus_ disimpan dengan format khusus. +Format ini sama untuk +link:#glos-seed-corpus[bibit _corpus_], +dan +link:#glos-generated-corpus[bangkitan _corpus_]. + +Berikut contoh berkas _corpus_: + +---- +go test fuzz v1 +[]byte("hello\\xbd\\xb2=\\xbc ⌘") +int64(572293) +---- + +Baris pertama memberi tahu mesin _fuzzing_ versi berkas _corpus_. +Walaupun belum ada rencana ke depan untuk versi berkas terbaru, mesin +_fuzzing_ telah dirancang untuk mendukung hal tersebut. + +Baris-baris selanjutnya adalah nilai-nilai dari _corpus_, yang dapat +langsung disalin ke kode Go bila diinginkan. + +Pada contoh di atas, nilai _corpus_ adalah sebuah `[]byte` diikuti oleh +sebuah `int64`. +Tipe-tipe ini harus sesuai dengan argumen _fuzzing_, secara berurutan. +Bentuk target fuzz dari tipe-tipe tersebut akan seperti berikut: + +---- +f.Fuzz(func(*testing.T, []byte, int64) {}) +---- + +Cara termudah untuk menambahkan nilai bibit _corpus_ secara manual yaitu +dengan menggunakan method `(*testing.F).Add`. +Pada contoh di atas, caranya seperti berikut: + +---- +f.Add([]byte("hello\\xbd\\xb2=\\xbc ⌘"), int64(572293)) +---- + +Bila Anda memiliki berkas binari yang berukuran besar yang tidak +ingin disalin sebagai kode ke dalam tes, namun ingin digunakan sebagai isi +bibit _corpus_ dalam direktori `testdata/fuzz/{FuzzTestName}`. +Perkakas +https://pkg.go.dev/golang.org/x/tools/cmd/file2fuzz[file2fuzz^] +yang ada di dalam +`golang.org/x/tools/cmd/file2fuzz` +dapat digunakan untuk mengonversi berkas binari tersebut menjadi berkas +_corpus_ yang disimpan menjadi `[]byte`. + +Untuk menggunakan perkakas ini: + +---- +$ go install golang.org/x/tools/cmd/file2fuzz@latest +$ file2fuzz -h +---- + +== Sumber terkait + +* *Tutorial* +** Cobalah + link:/doc/tutorial/fuzz/[tutorial Go _fuzzing_^] untuk mendalami konsep + _fuzzing_. +** Untuk yang lebih singkat, tutorial perkenalan _fuzzing_ pada Go, silahkan + lihat + https://go.dev/blog/fuzz-beta/[blog^]. +* *Dokumentasi* +** Dokumentasi paket + https://pkg.go.dev/testing#hdr-Fuzzing[`testing`^] + menjelaskan tipe `testing.F` yang digunakan saat menulis fuzz tes. +** Dokumentasi paket + https://pkg.go.dev/cmd/go[`cmd/go`^] + menjelaskan opsi-opsi yang berkaitan dengan _fuzzing_. +* *Detil teknis* +** https://go.dev/s/draft-fuzzing-design[Draf rancangan _fuzzing_^] +** https://go.dev/issue/44551[Proposal^] + + +[#glossary] +== Glosarium + +[#glos-fuzzing-arguments] +*argumen _fuzzing_*: Tipe-tipe yang akan dikirim ke target fuzz, dan +dimutasi oleh +link:#glos-mutator[mutator]. + +[#glos-generated-corpus] +*bangkitan _corpus_*: Sebuah _corpus_ yang diatur oleh mesin _fuzzing_ saat +_fuzzing_ berjalan untuk mencatat progres. +Ia disimpan dalam `$GOCACHE/fuzz`. +Isi dari bangkitan _corpus_ ini hanya digunakan saat _fuzzing_. + +[#glos-test-file] +*berkas tes*: Sebuah berkas dengan format `xxx_test.go` yang bisa berisi +tes-test, _benchmark_, contoh-contoh kode dan fuzz tes. + +[#glos-seed-corpus] +*bibit _corpus_*: _Corpus_ yang disediakan oleh pengembang untuk sebuah +fuzz tes yang dapat digunakan sebagai panduan bagi mesin _fuzzing_. +Isi _corpus_ dibentuk dari pemanggilan +`f.add` di dalam fuzz tes, dan dari berkas-berkas di dalam direktori +`testdata/fuzz/{FuzzTestName}` dari paket yang diuji. +Isi-isi bibit _corpus_ ini dijalankan oleh `go test` baik bila dijalankan +dengan opsi _fuzzing_ atau tidak. + +[#glos-vulnerability] +*celah keamanan*: Kelemahan keamanan dalam kode yang dapat di-eksploitasi +oleh peretas. + +[#glos-fuzz-test] +*fuzz tes*: Sebuah fungsi dalam berkas tes dengan bentuk `func +FuzzXxx(*testing.F)` yang dapat digunakan untuk _fuzzing_. + +[#glos-fuzzing] +*fuzzing*: Sebuah tipe dari pengujian otomatis yang secara terus menerus +memanipulasi input pada sebuah program untuk menemukan kesalahan seperti +_bug_ atau +link:#glos-vulnerability[celah keamanan] +pada kode. + +[#glos-failing-input] +*input gagal*: Sebuah input yang gagal yaitu isi _corpus_ yang akan +menyebabkan sebuah kegagalan atau _panic_ saat dijalankan terhadap +link:#glos-fuzz-target[target fuzz]. + +[#glos-corpus-entry] +*isi _corpus_*: Sebuah input dalam _corpus_ yang dapat digunakan saat +_fuzzing_. +Isi _corpus_ bisa berupa berkas dengan format khusus, atau pemanggilan +ke +https://pkg.go.dev/testing#F.Add[`(*testing.F).Add`^] + +[#glos-fuzzing-engine] +*mesin _fuzzing_*: Sebuah perkakas yang mengatur _fuzzing_, termasuk +menjaga _corpus_, memanggil mutator, meng-identifikasi cakupan yang baru, +dan melaporkan kegagalan. + +[#glos-mutator] +*mutator*: Sebuah perkakas yang digunakan saat _fuzzing_ yang secara acak +memanipulasi isi _corpus_ sebelum mengirimnya ke target fuzz. + +[#glos-package] +*paket*: Kumpulan berkas sumber kode dalam direktori yang sama yang +dikompilasi bersamaan. +Lihat +link:/ref/spec#Packages[bab Paket^] +dalam Spesifikasi Bahasa Go. + +[#glos-coverage-guidance] +*panduan cakupan*: Sebuah metoda _fuzzing_ yang menggunakan ekspansi dalam +cakupan kode untuk menentukan isi _corpus_ mana yang pantas disimpan untuk +penggunaan dimasa depan. + +[#glos-fuzz-target] +*target fuzz*: Fungsi dari fuzz tes yang dieksekusi dengan isi _corpus_ dan +menghasilkan nilai saat _fuzzing_ berjalan. +Sebuah target fuzz diberikan pada fuzz tes dengan mengirim fungsi tersebut +ke +https://pkg.go.dev/testing#F.Fuzz[`(*testing.F).Fuzz`^]. + + +== Umpan balik + +Jika Anda mengalami masalah atau memiliki ide untuk sebuah fitur, silahkan +https://go.dev/issue/new?&labels=fuzz[kirim isu^]. + +Untuk diskusi dan umpan balik umum tentang fitur, Anda juga dapat +berpartisipasi dalam +https://gophers.slack.com/archives/CH5KV1AKE["kanal #fuzzing"^] +di Gophers Slack. diff --git a/_content/doc/security/fuzz/technical.adoc b/_content/doc/security/fuzz/technical.adoc new file mode 100644 index 0000000..b26b7e3 --- /dev/null +++ b/_content/doc/security/fuzz/technical.adoc @@ -0,0 +1,84 @@ +<!--{ + "Title": "Go Fuzzing technical details", + "Breadcrumb": true +}--> + +This document provides an overview of the technical details of the native fuzzing implementation, and is intended to be a resource for contributors. + +## General architecture + +The fuzzer uses a single coordinator process, which manages the corpus, and multiple worker processes, which mutate inputs and execute the fuzz target. The coordinator and worker processes communicate using a piped JSON-based RPC protocol, and shared regions of virtual memory. + +For each worker the coordinator creates a goroutine which spawns the worker process and sets up the cross-process communication. Each goroutine then reads from a shared channel which is fed by the main coordinator loop, sending instructions it reads from the channel to the relevant worker processes. + +The main coordinator loop picks inputs from the corpus, sending them to the shared worker channel. Whichever worker picks up that input from the channel will send a fuzzing request to the corresponding worker process. This process sits in a loop, mutating the input and executing the fuzz target until an execution either causes an increase in the coverage counters, causes a panic or crash, or passes a predetermined deadline. + +If the worker process executes a mutated input which causes an increase in coverage counters or a recoverable panic, it signals this to the coordinator which is then able to reconstruct the mutated input. The coordinator will attempt to [minimize the input](#input-minimization), then either add it to the corpus for further fuzzing, in the case of finding increased coverage, or write it to the testdata directory, in the case of an input which causes an error or panic. + +If a non-recoverable error occurs while fuzzing which causes the worker process to shut down (e.g. infinite loop, os.Exit, memory exhaustion, etc), minimization will not be attempted, and the failing input will be written to the testdata directory and reported. + +<img alt="Sequence diagram of the interaction between coordinator and worker, as described above." src="/security/fuzz/seq-diagram.png"/> + +### Cross-process communication + +When spawning the child worker processes, the coordinator sets up two methods of communication: a pipe, which is used to pass JSON-based RPC messages, and a shared memory region, which is used to pass inputs and RNG state. Each worker process has its own pipe and shared memory region. + +The RPC pipe is used by the coordinator to control the worker process, sending it either fuzzing or minimization instructions, and by the worker to relay results of its operations to the coordinator (i.e. whether the input expanded coverage, caused a crash, was successfully minimized, etc). + +The shared memory region is used to pass specific information back and forth with the workers. The coordinator uses the region to pass the corpus entry to fuzz to the worker, and is used by the worker to store its current RNG state. The RNG state is used by the coordinator to reconstruct the mutations that were applied to the input by the worker when it has finished executing the target (this reconstruction happens both when the worker exits cleanly, and when it crashes.) + +## Input selection + +The coordinator currently does not implement any advanced form of input prioritization. It cycles through the entire corpus, looping after it exhausts the entries. + +Similarly, the coordinator does not implement any type of corpus minimization (not to be confused with input minimization, [discussed below](#input-minimization)). + +## Coverage guidance + +The fuzzer uses [libFuzzer compatible](https://clang.llvm.org/docs/SanitizerCoverage.html#inline-8bit-counters) inline 8 bit coverage counters. These counters are inserted during compilation at each code edge, and are incremented on entry. Counters are not protected against overflow, so that they don't become saturated. + +Similarly to AFL and libFuzzer, when tracking coverage, the counters are quantized to the nearest power of two. This allows the fuzzer to differentiate between insignificant and significant changes in execution flow. In order to track these changes, the fuzzer holds a slice of bytes which map to the inline counters, the bits of which indicate if there is at least one input in the corpus which increments the related counter at least 2^bit-position times. These bytes can become saturated, if there are inputs which cause counters to hit each quantized value, at which point the related counter fails to provide further useful coverage information. + +As coverage counters are added to every edge during compilation, code not being fuzzed is also instrumented, which can cause the worker to detect coverage expansion that is unrelated to the target being executed (for instance if some new code path is triggered in a goroutine unrelated to the fuzz target). The worker attempts to reduce this in two ways: firstly it resets all counters immediately before executing the fuzz target and then snapshots the counters immediately after the target returns, and secondly by explicitly ignoring a set of packages which are likely to be "noisy" + +A number of packages explicitly do not have counters inserted, since they are likely to introduce counter noise that is unrelated to the target being executed. These packages are: + +* `context` +* `internal/fuzz` +* `reflect` +* `runtime` +* `sync` +* `sync/atomic` +* `syscall` +* `testing` +* `time` + +## Mutation engine + +When the worker receives a new input, it applies mutations to the input before executing the target with the input. After each mutation, the fuzz target is executed with the new input, and if coverage is not expanded, further mutations are applied. In order to prevent inputs from massively diverging from their initial state, after five mutations are applied to an input, it is reset to its original state before further mutations are applied. For example for the input `hello world`, the mutation strategy may look like the following: + +``` +0. hello world [initial state] +1. kello world [replace first byte] +2. world kello [swap two chunks] +3. world ke [delete last three bytes] +4. owrld ke [shuffle first three bytes] +5. owrldx ke [insert random byte] +6. ello world [reset to initial state, delete first byte] +... +``` + +The mutators attempt to bias towards producing smaller inputs, rather than larger inputs, in order to prevent rapid growth of the corpus size. + +There are numerous mutators for `[]byte` and `string` types, and a smaller number of mutators for all the `int`, `uint`, and `float` types. + +There are currently no execution driven mutation strategies implemented (such as input-to-comparison correspondence), nor dictionary based mutators. + +## Input minimization + +In order to prevent the corpus from ballooning (which bogs down the fuzzer both in terms of performance, and reducing the probability that a mutation will actually touch interesting data) we attempt to minimize each input discovered which expands coverage or causes a recoverable crash (non-recoverable crashes, such as those caused by memory exhaustion, are not minimized, as the process would be extremely slow). The employed strategy for minimization is rather simple, sequentially attempting to remove bytes from the input while maintaining the initial coverage found. In particular the minimization mechanism uses the following strategy: + +1. Attempt to cut an exponentially smaller chunk of bytes off the end of the input +2. Attempt to remove each individual byte +3. Attempt to remove each possible subset of bytes +4. Attempt to replace each non-human readable byte with a human readable byte (i.e. something in the ASCII set of bytes) diff --git a/_content/doc/tutorial/fuzz/index.adoc b/_content/doc/tutorial/fuzz/index.adoc index 360b618..17d59e2 100644 --- a/_content/doc/tutorial/fuzz/index.adoc +++ b/_content/doc/tutorial/fuzz/index.adoc @@ -14,7 +14,7 @@ fungsi sederhana, mempelajari perintah-perintah go test untuk _fuzzing_, dan mencari dan memperbaiki isu-isu yang ditemukan fuzz tes. Untuk informasi lebih lanjut tentang terminologi dalam tutorial ini, lihatlah -https://go.dev/security/fuzz/[glosarium Go _Fuzzing_^]. +link:/doc/security/fuzz/#glossary[glosarium Go _Fuzzing_^]. Kita akan mempelajari beberapa bagian-bagian berikut, @@ -29,7 +29,7 @@ NOTE: Untuk tutorial lainnya, lihat link:/doc/tutorial/[Tutorial]. NOTE: Saat ini _fuzzing_ pada Go hanya mendukung sebagian dari tipe-tipe bawaan, yang terdaftar di -https://go.dev/security/fuzz/#requirements[dokumentasi Go Fuzzing^], +link:/doc/security/fuzz/#requirements[dokumentasi Go Fuzzing^], dukungan tipe bawaan lainnya akan ditambahkan di masa depan. @@ -803,10 +803,10 @@ Pengujian _fuzz_ sukses! Sebagai tambahan dari opsi `-fuzz`, ada beberapa opsi baru yang telah ditambahkan ke `go test` yang dapat dilihat di -https://go.dev/security/fuzz/#custom-settings[dokumentasi^]. +link:/doc/security/fuzz/#custom-settings[dokumentasi^]. Lihat -https://go.dev/security/fuzz/#command-line-output[Go Fuzzing^] +link:/doc/security/fuzz/#command-line-output[Go Fuzzing^] untuk informasi lebih lanjut tentang istilah-istilah pada keluaran _fuzzing_. Misalnya, istilah "new interesting" mengacu pada input-input baru yang telah ditambahkan sesuai cakupan kode dari _corpus_ fuzz tes yang telah ada. @@ -837,7 +837,7 @@ https://gophers.slack.com/archives/CH5KV1AKE["kanal #fuzzing"^] di Slack Gophers. Lihatlah dokumentasi tentang -https://go.dev/security/fuzz/[Go Fuzzing^] +link:/doc/security/fuzz/[Go Fuzzing^] untuk bacaan lebih lanjut. |
