• Stars
    star
    112
  • Rank 312,240 (Top 7 %)
  • Language
    Rust
  • License
    Apache License 2.0
  • Created almost 2 years ago
  • Updated 12 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

erlfuzz is a fuzzer for the Erlang ecosystem

Erlfuzz

erlfuzz is a small standalone generator of random erlang programs used to fuzz the erlang compiler and VM (and other tools such as erlfmt, dialyzer, eqWAlizer, etc.). It does not currently use coverage information or do anything especially clever, except for carefully handling Erlang's scoping rules.

Requirements

Dependencies of the fuzzer itself:

Dependencies of the scripts wrapping fuzzing targets:

  • Bash
  • GNU Parallel
  • Timeout (part of GNU coreutils)

The fuzzer has been tested on both Linux and MacOS. On the latter, the scripts need a small tweak to run: removing or replacing calls to the ulimit command.

How to build

On a machine with access to the internet: cargo build --release

How to use

With a provided script

If the goal is to fuzz erlc & erl, the easiest way is to use the provided run_erl_once.sh script from erlfuzz/ as follows:

mkdir -p out
mkdir -p interesting
seq 1000000 | parallel --line-buffer "./target/release/erlfuzz fuzz -c ./run_erl_once.sh --tmp-directory out --interesting-directory interesting test{}"

This will repeatedly run the fuzzer, store its output in a file in out/, call erlc and erl on that file, and then either delete it or move it to interesting/ if it triggered a crash. It will automatically make use of all cores on your machine. If that is not what you want, you can limit it to 5 cores (for example) by passing -j 5 to parallel. It will automatically stop after 1M iterations, just increase the parameter to seq if you want more.

I recommend running this in a window controlled by tmux, screen, etc., so it can be detached and survive the end of whatever terminal/ssh session you are using.

There are similar scripts for fuzzing other tools such as erlfmt, dialyzer, or eqwalizer. For some of these, it may be required to pass additional options to erlfuzz:

  • run_eqwalizer_once.sh:
    • --disable-maybe
    • --disable-shadowing
  • run_gradualizer_once.sh:
    • --disable-map-comprehensions
    • --disable-maybe
  • run_erlfmt_once.sh:
    • --disable-map-comprehensions
    • --disable-maybe
  • run_infer_once.sh:
    • --disable-map-comprehensions
    • --disable-maybe
    • --disable-shadowing
    • --wrapper for-infer
  • verify_erl_jit.sh:
    • --deterministic
    • --wrapper printing
  • verify_erlc_opts.sh:
    • --deterministic
    • --wrapper printing
  • verify_infer_against_erl.sh:
    • --deterministic
    • --disable-map-comprehensions
    • --disable-maybe
    • --disable-shadowing
    • --wrapper printing

With another script

erlang fuzz can be used to fuzz any other command that accepts an Erlang file. A return code of 0 must be used to indicate that the program ran successfully, and non-0 to report that a bug was found. I strongly recommend wrapping the program being fuzzed by a script that uses timeout and ulimit -m; you can look at run_erl_once.sh for inspiration. Also consider using stronger sandboxing (e.g. with cgroups) if the program under test is likely to have dangerous side effects.

Manually

Instead of using erlfuzz fuzz on a script like above, you can use erlfuzz to generate an Erlang file on stdout, which you can then use however you want. See erlfuzz generate for details.

Testcase minimization

Testcases found by erlfuzz can be automatically reduced, by using erlfuzz reduce, and passing it the seed used to generate the testcase. If any additional option was passed during generation time, it must also be passed at reduction time. Both the seed and all relevant options are listed in a comment at the top of the testcase.

For example:

./target/release/erlfuzz reduce -c ./run_erl_once.sh --tmp-directory out --minimized-directory minimized --seed 3137934125722527840 foobar

Would reduce the testcase that was generated with seed 3137934125722527840, use out/foobar.erl as a scratch file, and store the result in minimized/foobar.erl.

Depending on the formatting of the error messages that are output by the tool under test, it can be necessary to adjust the similarity heuristic with the --max-distance or the --num-lines options. Dialyzer for example includes non-deterministic numbers (timestamp, process id) in its error messages, so --max-distance 10 is required for erlfuzz to ignore those.

You can ask erlfuzz to automatically reduce the bugs it finds as they are found, by using erlfuzz fuzz-and-reduce. This is a tiny wrapper around doing erlfuzz fuzz followed by erlfuzz reduce, and needs all of the same arguments.

Debugging erlfuzz

If erlfuzz itself is misbehaving, one way to investigate is to set the environment variable RUST_LOG=debug or RUST_LOG=trace (even more verbose) to make it emit a log of its actions to stderr. It is possible to set different modules to different levels of logging, for example RUST_LOG="warn,erlfuzz::reducer=info" will set all modules to level "warn" except for the testcase reducer which it will set to level info. See crate env_logger for details. The levels from least to most verbose are:

  • error (default)
  • warn
  • info
  • debug
  • trace

I recommend the following setting to get a log of progress during reduction: RUST_LOG="debug,erlfuzz::environment=warn".

License

erlfuzz is Apache licensed.

Current limitations

None of the following is currently generated by the fuzzer:

  • receive and ! (and more generally the code generated is currently non-concurrent)
  • records
  • preprocessor commands
  • map iterators

Erlfuzz also only knows about some bifs. In particular, it does not yet generate any code using the ets module.

Some of the bugs found so far

BEAM VM:

erlc:

dialyzer:

erlfmt:

eqWAlizer:

inferl:

Gradualizer

More Repositories

1

stickers

This repository contains the iOS and Android sample apps and API for creating third party sticker packs for WhatsApp.
Java
2,711
star
2

proxy

This repository contains the WhatsApp proxy implementation for users to host their own proxy infrastructure to connect to WhatsApp for chat (VoIP is not currently supported)
Shell
1,163
star
3

waraft

An Erlang implementation of RAFT from WhatsApp
Erlang
508
star
4

eqwalizer

A type-checker for Erlang
Erlang
477
star
5

erlfmt

An automated code formatter for Erlang
Erlang
391
star
6

WhatsApp-Business-API-Setup-Scripts

The scripts related to setting up WhatsApp business API
373
star
7

erlt

Early prototype of ErlT, an experimental Erlang dialect with first-class support for static typing.
Erlang
127
star
8

StringPacks

Extracts localized strings from an Android app and stores it in a much more efficient format.
Java
124
star
9

WhatsApp-Nodejs-SDK

The official Meta Business Messaging WhatsApp Cloud API Node.js SDK.
TypeScript
102
star
10

erlang-language-platform

Erlang Language Platform. LSP server and CLI.
Rust
77
star
11

power_shell

Erlang shell with advanced features: evaluating non-exported functions and shortcuts for frequently used functions.
Erlang
74
star
12

tree-sitter-erlang

Tree-sitter Grammar for Erlang
C
65
star
13

WADebug

WhatsApp Debug - A command-line tool that will be used to troubleshoot installation of WhatsApp Business API.
Python
30
star
14

whatsapp-business-api-deployment-templates

This repo hosts the cloud templates which enable one-click deployment of their WhatsApp Business Platform On-Premise API on different cloud platforms with stable high messaging throughput.
HCL
24
star
15

erldist_filter

erldist_filter NIF for filtering and logging Erlang Dist Protocol messages
C
13
star
16

WhatsApp-OTP-Sample-App

Sample app that integrates with WhatsApp OTP (One-Time Password) copy code and "one-tap" autofill features. This project shows how to send and receive OTP code from WhatsApp and best practices around integration.
Swift
10
star
17

WhatsApp-Android-OTP-SDK

WhatsApp Android OTP SDK helps you integrate with one-time password solution provided by WhatsApp.It provides handy functions that simplifies the integration work.
Java
4
star
18

WhatsApp-Flows-Tools

Tools and examples to help you create WhatsApp Flows https://developers.facebook.com/docs/whatsapp/flows
1
star