Fuzz-Testing the Snappy Compression Algorithm by fuzz-ai

View this thread on steempeak.com
· @fuzz-ai ·
$0.33
Fuzz-Testing the Snappy Compression Algorithm
* Using [American Fuzzy Lop](http://lcamtuf.coredump.cx/afl/) on the Snappy compression library found no new bugs, and reported only high memory usage related to preallocation of an output buffer.
 * Users of Snappy should be aware of this preallocation and check the uncompressed size before calling `snappy::Uncompress`
 * Non-C++ implementation of Snappy have had bugs reported by AFL-derived tools.

# Snappy

Snappy is a compression library (https://github.com/google/snappy) that is optimized for speed rather than achieving the maximum compression.  It’s used in a several NoSQL databases, and in the Ripple blockchain implementation.

Compression algorithms, like parsing libraries, are usually a good target for fuzzing. By their very nature, inputs to decompression are very compact, so small modifications are likely to explore new code paths.  We can also demonstrate using a fuzzer to check semantic correctness as well as security properties.

## Compiling Snappy and Creating a Test Harness

Snappy uses CMake so it was simple to replace its default compiler with `afl-g++` and `afl-gcc` to generate an instrumented library.

We created two test harnesses.  The first takes an uncompressed string and verifies that a compression/uncompression cycle results in the original string.  This sort of “round-trip” is common in property-based testing, and we can use it with a fuzzer as well to do a semantic check, rather than merely checking for memory violations or crashes.

```
#include <snappy.h>
#include <iostream>
#include <string>
#include <cstring>
#include <stdlib.h>

const size_t maxInputSize = 10 * 1024 * 1024;

char inputBuf[maxInputSize];

int main( int argc, char *argv[] ) {
  std::cin.read( inputBuf, maxInputSize );
  size_t inputLength = std::cin.gcount();

  std::string compressed;
  snappy::Compress( inputBuf, inputLength, &compressed );

  std::string uncompressed;
  snappy::Uncompress( compressed.data(), compressed.size(),
                      &uncompressed );

  if ( uncompressed.size() != inputLength ) {
    std::cout << "Size mismatch.";
    abort();
  }
  
  if ( memcmp( uncompressed.data(), inputBuf, inputLength ) != 0 ) {
    std::cout << "Content mismatch.";
    abort();
  }

  return 0;
}
```
Gist: https://gist.github.com/fuzz-ai/a4a2c06116a90a3d793df87701dc5f8c

To test the robustness of uncompression, we feed the original input buffer into Decompress instead:

```
  std::string uncompressed;
  snappy::Uncompress( inputBuf, inputLength,
                  	&uncompressed );
```

##  Test case generation and results
Snappy includes some files for testing and benchmarking; these are not really suitable for fuzzing, because they are quite large (as is appropriate for a speed-oriented library!)  Even several hundred kilobytes make some of the AFL fuzzing steps quite slow, and it is unusual for a bug to require a large input to manifest.

AFL even suggested that one of the test cases could be removed

```
[*] Attempting dry run with 'id:000004,orig:baddata3.snappy'...
	len = 28384, map size = 136, exec speed = 369 us
[!] WARNING: No new instrumentation output, test case may be useless.
```

The program `afl-cmin` (for “corpus minimization”) can be used to filter an initial set of test cases to one where each example has at least one distinct code path.

So, for testing purposes, I cut the provided files down to 1KB each, except for the “bad data” cases which were left as-is.

![image1.png](https://cdn.steemitimages.com/DQmYWt7tz5MDZjULURmNNA4tG9uiEyt3hdrnbLddpCV7yjB/image1.png)

AFL ran several million iterations without finding any significant bugs.  As the screen above shows, it is rather easy for the fuzzer to find cases where decompression crashes, but this is due to the 50MB limit on memory allocation.

# Analysis
It seems likely that this is not the first attempt to fuzz Snappy, though I cannot find any indication of previously-reported bugs credited to AFL or another tool.

Other implementations of Snappy have been fuzzed successfully; for example, the Rust implementation had an error discovered by `afl-rust`: https://github.com/BurntSushi/rust-snappy/issues/12

The Snappy C++ interface uses a `std::string` as output and resizes it at the start of uncompression:

```
bool Uncompress(const char* compressed, size_t n, string* uncompressed) {
  size_t ulength;
  if (!GetUncompressedLength(compressed, n, &ulength)) {
	return false;
  }
  // On 32-bit builds: max_size() < kuint32max.  Check for that instead
  // of crashing (e.g., consider externally specified compressed data).
  if (ulength > uncompressed->max_size()) {
	return false;
  }
  STLStringResizeUninitialized(uncompressed, ulength);
  return RawUncompress(compressed, n, string_as_array(uncompressed));
}
```

The maximum size on 64-bit systems is quite large, so this is a possible vector for memory exhaustion attacks if clients use this method without checking `GetUncompressedLength`first.  We need not use a fuzzer to investigate this possibility, since the first four bytes of the Snappy format give us a way to set the uncompressed length in a straightforward fashion.

After the fuzzer has generated its corpus of examples, we could use a standard coverage tool to compare how well the results compare with the benchmarking inputs included with Snappy. Such automatic generation of test cases usually does much better than hand-crafted examples; we'll show an example of this in another article.

# Fuzz.ai

[Fuzz.ai](http://www.fuzz.ai/) is an early-stage startup dedicated to making software correctness tools easier to use. Fuzzers, model checkers, and property-based testing can make software more robust, expose security vulnerabilities, and speed development.
👍  , , , , , , , , , , , , , , , , , , , ,
properties (23)
post_id67,708,681
authorfuzz-ai
permlinkfuzz-testing-the-snappy-compression-algorithm
categorysoftware
json_metadata{"links":["http:\/\/lcamtuf.coredump.cx\/afl\/","https:\/\/github.com\/google\/snappy","https:\/\/gist.github.com\/fuzz-ai\/a4a2c06116a90a3d793df87701dc5f8c","https:\/\/github.com\/BurntSushi\/rust-snappy\/issues\/12","http:\/\/www.fuzz.ai\/"],"format":"markdown","image":["https:\/\/cdn.steemitimages.com\/DQmYWt7tz5MDZjULURmNNA4tG9uiEyt3hdrnbLddpCV7yjB\/image1.png"],"app":"steemit\/0.1","tags":["software","security","programming","fuzzing","compression"]}
created2018-12-21 06:14:33
last_update2018-12-21 06:14:33
depth0
children5
net_rshares601,029,954,440
last_payout2018-12-28 06:14:33
cashout_time1969-12-31 23:59:59
total_payout_value0.253 SBD
curator_payout_value0.077 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length5,731
author_reputation1,041,784,227,026
root_title"Fuzz-Testing the Snappy Compression Algorithm"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
author_curate_reward""
vote details (21)
@steemitboard ·
Congratulations @fuzz-ai! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :

<table><tr><td>https://steemitimages.com/60x60/http://steemitboard.com/notifications/firstcommented.png</td><td>You got a First Reply</td></tr>
<tr><td>https://steemitimages.com/60x70/http://steemitboard.com/@fuzz-ai/voted.png?201812211057</td><td>You received more than 100 upvotes. Your next target is to reach 250 upvotes.</td></tr>
</table>

<sub>_[Click here to view your Board of Honor](https://steemitboard.com/@fuzz-ai)_</sub>
<sub>_If you no longer want to receive notifications, reply to this comment with the word_ `STOP`</sub>



> Support [SteemitBoard's project](https://steemit.com/@steemitboard)! **[Vote for its witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1)** and **get one more award**!
properties (22)
post_id67,719,401
authorsteemitboard
permlinksteemitboard-notify-fuzz-ai-20181221t115150000z
categorysoftware
json_metadata{"image":["https:\/\/steemitboard.com\/img\/notify.png"]}
created2018-12-21 11:51:48
last_update2018-12-21 11:51:48
depth1
children0
net_rshares0
last_payout2018-12-28 11:51:48
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length892
author_reputation38,705,954,145,809
root_title"Fuzz-Testing the Snappy Compression Algorithm"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
@steemitboard ·
Congratulations @fuzz-ai! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :

<table><tr><td>https://steemitimages.com/60x60/http://steemitboard.com/notifications/firstpayout.png</td><td>You got your First payout</td></tr>
</table>

<sub>_[Click here to view your Board](https://steemitboard.com/@fuzz-ai)_</sub>
<sub>_If you no longer want to receive notifications, reply to this comment with the word_ `STOP`</sub>



**Do not miss the last post from @steemitboard:**
<table><tr><td><a href="https://steemit.com/christmas/@steemitboard/christmas-challenge-send-a-gift-to-to-your-friends"><img src="https://steemitimages.com/64x128/http://i.cubeupload.com/kf4SJb.png"></a></td><td><a href="https://steemit.com/christmas/@steemitboard/christmas-challenge-send-a-gift-to-to-your-friends">Christmas Challenge - Send a gift to to your friends</a></td></tr></table>

> Support [SteemitBoard's project](https://steemit.com/@steemitboard)! **[Vote for its witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1)** and **get one more award**!
properties (22)
post_id67,854,396
authorsteemitboard
permlinksteemitboard-notify-fuzz-ai-20181224t134453000z
categorysoftware
json_metadata{"image":["https:\/\/steemitboard.com\/img\/notify.png"]}
created2018-12-24 13:44:51
last_update2018-12-24 13:44:51
depth1
children0
net_rshares0
last_payout2018-12-31 13:44:51
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length1,135
author_reputation38,705,954,145,809
root_title"Fuzz-Testing the Snappy Compression Algorithm"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
@steemitboard ·
Congratulations @fuzz-ai! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :

<table><tr><td>https://steemitimages.com/60x70/http://steemitboard.com/@fuzz-ai/payout.png?201812260231</td><td>You received more than 10 as payout for your posts. Your next target is to reach a total payout of 50</td></tr>
</table>

<sub>_[Click here to view your Board](https://steemitboard.com/@fuzz-ai)_</sub>
<sub>_If you no longer want to receive notifications, reply to this comment with the word_ `STOP`</sub>



**Do not miss the last post from @steemitboard:**
<table><tr><td><a href="https://steemit.com/christmas/@steemitboard/christmas-challenge-send-a-gift-to-to-your-friends-the-party-continues"><img src="https://steemitimages.com/64x128/http://i.cubeupload.com/kf4SJb.png"></a></td><td><a href="https://steemit.com/christmas/@steemitboard/christmas-challenge-send-a-gift-to-to-your-friends-the-party-continues">Christmas Challenge - The party continues</a></td></tr><tr><td><a href="https://steemit.com/christmas/@steemitboard/christmas-challenge-send-a-gift-to-to-your-friends"><img src="https://steemitimages.com/64x128/http://i.cubeupload.com/kf4SJb.png"></a></td><td><a href="https://steemit.com/christmas/@steemitboard/christmas-challenge-send-a-gift-to-to-your-friends">Christmas Challenge - Send a gift to to your friends</a></td></tr></table>

> Support [SteemitBoard's project](https://steemit.com/@steemitboard)! **[Vote for its witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1)** and **get one more award**!
properties (22)
post_id67,915,929
authorsteemitboard
permlinksteemitboard-notify-fuzz-ai-20181226t030859000z
categorysoftware
json_metadata{"image":["https:\/\/steemitboard.com\/img\/notify.png"]}
created2018-12-26 03:08:57
last_update2018-12-26 03:08:57
depth1
children0
net_rshares0
last_payout2019-01-02 03:08:57
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length1,619
author_reputation38,705,954,145,809
root_title"Fuzz-Testing the Snappy Compression Algorithm"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
@steemitboard ·
Congratulations @fuzz-ai! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :

<table><tr><td>https://steemitimages.com/60x70/http://steemitboard.com/@fuzz-ai/payout.png?201812260708</td><td>You received more than 50 as payout for your posts. Your next target is to reach a total payout of 100</td></tr>
</table>

<sub>_[Click here to view your Board](https://steemitboard.com/@fuzz-ai)_</sub>
<sub>_If you no longer want to receive notifications, reply to this comment with the word_ `STOP`</sub>



**Do not miss the last post from @steemitboard:**
<table><tr><td><a href="https://steemit.com/christmas/@steemitboard/christmas-challenge-send-a-gift-to-to-your-friends-the-party-continues"><img src="https://steemitimages.com/64x128/http://i.cubeupload.com/kf4SJb.png"></a></td><td><a href="https://steemit.com/christmas/@steemitboard/christmas-challenge-send-a-gift-to-to-your-friends-the-party-continues">Christmas Challenge - The party continues</a></td></tr><tr><td><a href="https://steemit.com/christmas/@steemitboard/christmas-challenge-send-a-gift-to-to-your-friends"><img src="https://steemitimages.com/64x128/http://i.cubeupload.com/kf4SJb.png"></a></td><td><a href="https://steemit.com/christmas/@steemitboard/christmas-challenge-send-a-gift-to-to-your-friends">Christmas Challenge - Send a gift to to your friends</a></td></tr></table>

> Support [SteemitBoard's project](https://steemit.com/@steemitboard)! **[Vote for its witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1)** and **get one more award**!
properties (22)
post_id67,923,474
authorsteemitboard
permlinksteemitboard-notify-fuzz-ai-20181226t075623000z
categorysoftware
json_metadata{"image":["https:\/\/steemitboard.com\/img\/notify.png"]}
created2018-12-26 07:56:24
last_update2018-12-26 07:56:24
depth1
children0
net_rshares0
last_payout2019-01-02 07:56:24
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length1,620
author_reputation38,705,954,145,809
root_title"Fuzz-Testing the Snappy Compression Algorithm"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
@bobinson ·
Thats impressive snappy ;-)
properties (22)
post_id69,876,473
authorbobinson
permlinkre-fuzz-ai-fuzz-testing-the-snappy-compression-algorithm-20190208t060310426z
categorysoftware
json_metadata{"tags":["software"],"app":"steemit\/0.1"}
created2019-02-08 06:03:12
last_update2019-02-08 06:03:12
depth1
children0
net_rshares0
last_payout2019-02-15 06:03:12
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length27
author_reputation18,620,871,366,628
root_title"Fuzz-Testing the Snappy Compression Algorithm"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000