Skip to content
A fuzzer for the Rust compiler. Mostly for my own entertainment.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
ruby-utils
to_investigate
.gitignore
Cargo.toml
Gemfile
Gemfile.lock
LICENSE
README.md
fuzzer.rb
tweet.rb

README.md

Fuzzy Wuzzy

A Rust compiler fuzzer written for my own education and entertainment. I was inspired by John Regehr's talk at the Bay Area Rust Meetup, especially the part where he said (49:15):

"If there are multiple fuzzers, then that's totally awesome because it's always the case that two fuzzers, even one that's really smart and one that's really stupid, the really stupid one will always find stuff that the smart one doesn't find just because we don't understand what's going on at all..."

This really spoke to me :) I can write a really stupid fuzzer!!!

Named by the ever-wonderful tenderlove ❤️

To Run

ruby fuzzer.rb will generate then attempt to compile Rust code in src/lib.rs until either compilation fails (at which point the offending code will still be in that file for analysis) or you force quit.

Other options

  • DEBUG=true ruby fuzzer.rb will print more information about which choices the Ruby code made.

  • MAX=5 ruby fuzzer.rb will adjust the maximum number used when deciding on a random number of times to generate something. Default is 10; the likely generated size of the Rust code and the time it takes to generate the Rust code will increase as this number increases.

  • CONSUMER_KEY=your-consumer-key CONSUMER_SECRET=your-consumer-secret ACCESS_TOKEN=your-access-token ACCESS_SECRET=your-access-secret ruby tweet.rb will tweet Rust code between 100 and 140 characters. It will not write to the file system or compile the Rust code. bundle before running to install the twitter gem, and create a new Twitter app to get the tokens.

TODO

As John hinted, I immediately wish I had a reducer. That is, a program that will take the code that fails and try taking stuff out of it to get a more minimal failure case. But I don't have that yet.

As far as code generation goes, here's the status:

  • Comments
  • Whitespace
  • Tokens
  • Paths
  • Macros
  • Crates
  • Items
    • extern_crate_decl
    • use_decl
    • mod_item
    • fn_item (empty args and return values only)
    • type_item
    • struct_item
    • enum_item
    • const_item
    • static_item
    • trait_item
    • impl_item
    • extern_block
  • Attributes
  • Statements
    • declaration statements
      • item declarations
      • slot declarations
    • expression statements
  • Expressions
  • Types

Info

Yes, the fuzzer part is written in Ruby. Look, I was recompiling Rust when I felt like starting it. I might redo it in Rust or something else sometime.

I'm basically working from the Rust Reference and, as John said in the talk, every time you are given a choice, take both!

Here's an example of what this generated:

mod vni0jht {  fn ttm() {  mod e_3 {  fn um4cnko() {  fn n() {  }  }  }  let g03r6gznp2: &'static str = "·ìǖ\nŪᚷŰ&;řᛧÞõ";
let h7fo8vzt: i8 = 0;
const NL: bool = true;  let uil6: char = 'X';
fn sh0k() {  mod i8 {  const G5AHRZ: &'static str = "\"Ľ¨ċǴNěţ·ᚣⱮ\0űƯŻěľȌ{\"\"";  }  let pnkfu3l04s: &'static str = "\r\\\0ĤȞ͵\0";
mod sl6c8 {  }  let u: &'static str = "ΊȖ\"";
const MK_: &'static str = "9ɄŀÒͽaⱤnjw";  }  }  }

See? Really stupid :)

Previously unknown Rust compiler bugs found by this fuzzer

  • None yet!

Things I have learned

License

MIT. See LICENSE.

You can’t perform that action at this time.