> On Mar 25, 2019, at 6:13 AM, Dave Rodgman <[email protected]> wrote:
> 
> On 19/03/2019 8:15 pm, Nick Terrell wrote:
>> Hi Dave,
>> 
>> I just saw you patches adding LZO-RLE, so I decided to fuzz the LZO
>> compressor and decompressor. I didn't find any crashes, but I found some edge
>> cases in the decompressor.
> 
> Hi Nick,
> 
> Thanks - I will take a look at this. These cases won't affect zram, which is
> currently the only place lzo-rle is used, because zram operates over complete
> pages, but I would prefer not to have this kind of edge case lurking.
> 
> Presumably the fuzzer generates inputs of various sizes - how large did you
> test up to?

I tested on inputs up to 4096 bytes large, which is the default, but the fuzzing
library libFuzzer has a flag -max_len which allows you to control the maximum
input size.

> thanks
> 
> Dave
> 
>> 
>> After compressing the empty input with lzo1x_1_compress() I get
>> [0x11, 0x00, 0x00] which is rejected by lzo1x_decompress_safe() on line 60
>> because *ip == 17 and in_len < 5 with error LZO_E_INPUT_OVERRUN.
>> 
>> After compressing the input [0x00] with lzorle1x_1_compress() I get
>> [0x11, 0x01, 0x00, 0x11, 0x00, 0x00] which is rejected by
>> lzo1x_decompress_safe() with error LZO_E_OUTPUT_OVERRUN.
>> 
>> I ported LZO to userspace by copying the headers from the kernel to
>> userspace and/or rewriting them. The fuzzers and ported LZO are in
>> a GitHub repo so it can be easily reproduced [1]. The compression
>> fuzzer is also included inline below.
>> 
>> ```
>> #undef NDEBUG
>> #include <string.h>
>> #include <stdint.h>
>> #include <stddef.h>
>> #include <stdlib.h>
>> #include <assert.h>
>> #include <stdio.h>
>> 
>> #include "lzo.h"
>> 
>> char wrkmem[LZO1X_MEM_COMPRESS];
>> 
>> #define RLE 1
>> 
>> extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
>>  size_t outSize = lzo1x_worst_compress(size);
>>  uint8_t* const out = (uint8_t*)malloc(outSize);
>>  assert(out);
>> #if RLE
>>  assert(LZO_E_OK == lzorle1x_1_compress(data, size, out, &outSize, wrkmem));
>> #else
>>  assert(LZO_E_OK == lzo1x_1_compress(data, size, out, &outSize, wrkmem));
>> #endif
>>  uint8_t* const rt = (uint8_t*)malloc(size);
>>  assert(rt);
>>  size_t rtsize = size;
>>  int const ret = lzo1x_decompress_safe(out, outSize, rt, &rtsize);
>>  if (ret != LZO_E_OK) {
>>    assert(size < 4);
>>    fprintf(stderr, "INPUT: ");
>>    for (size_t i = 0; i < size; ++i)
>>      fprintf(stderr, "%u ", (unsigned)data[i]);
>>    fprintf(stderr, "\nOUTPUT: ");
>>    for (size_t i = 0; i < outSize; ++i)
>>      fprintf(stderr, "%u ", (unsigned)out[i]);
>>    fprintf(stderr, "\nret = %d\n", ret);
>>  }
>>  assert(ret == LZO_E_OK);
>>  assert(rtsize == size);
>>  assert(memcmp(data, rt, size) == 0);
>>  free(out);
>>  free(rt);
>>  return 0;
>> }
>> ```
>> 
>> [1] https://github.com/terrelln/lzo-userspace-fuzz
>> 
>> Best,
>> Nick Terrell
>> 
> 
> IMPORTANT NOTICE: The contents of this email and any attachments are 
> confidential and may also be privileged. If you are not the intended 
> recipient, please notify the sender immediately and do not disclose the 
> contents to any other person, use it for any purpose, or store or copy the 
> information in any medium. Thank you.

Reply via email to