lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <31D143C0-D64F-4905-B25F-5C3630D38913@fb.com>
Date:   Tue, 19 Mar 2019 20:15:07 +0000
From:   Nick Terrell <terrelln@...com>
To:     "dave.rodgman@....com" <dave.rodgman@....com>,
        "linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
        Kernel Team <Kernel-team@...com>
Subject: Kernel LZO compressor

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.

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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ