Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add lzo #1862

Merged
merged 13 commits into from
Oct 23, 2018
Merged

Add lzo #1862

23 changes: 23 additions & 0 deletions projects/lzo/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright 2018 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
################################################################################

FROM gcr.io/oss-fuzz-base/base-builder
MAINTAINER info@oberhumer.com
RUN apt-get update && apt-get install -y make autoconf automake libtool wget
RUN wget -O lzo.tar.gz \
http://www.oberhumer.com/opensource/lzo/download/lzo-2.10.tar.gz
COPY *.c *.options build.sh $SRC/
COPY lzo_decompress_target_seeds $SRC/lzo_decompress_target_seeds
35 changes: 35 additions & 0 deletions projects/lzo/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/bin/bash -eu
# Copyright 2018 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
################################################################################

# build project
cd $SRC
tar xzf lzo.tar.gz
cd lzo-*
./configure && make -j$(nproc)

# build fuzzers
for file in $SRC/*.c;
do
name=$(basename $file .c)
$CC -c -I include -I minilzo -I include/lzo ${file} -o ${name}.o
$CXX $CXXFLAGS -std=c++11 -I include -I minilzo -I include/lzo ${name}.o \
-o $OUT/${name} -lFuzzingEngine src/.libs/liblzo2.a
done

# copy fuzzer options
cp $SRC/*.options $OUT/
zip -j $OUT/lzo_decompress_target_seed_corpus.zip $SRC/lzo_decompress_target_seeds/*
78 changes: 78 additions & 0 deletions projects/lzo/lzo_compress_target.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
# Copyright 2018 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
################################################################################
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
#include "minilzo.h"

/* Work-memory needed for compression. Allocate memory in units
* of 'lzo_align_t' (instead of 'char') to make sure it is properly aligned.
*/
#define HEAP_ALLOC(var,size) \
lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) ]

static HEAP_ALLOC(wrkmem, LZO1X_1_MEM_COMPRESS);

extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
int r;
lzo_uint out_len;
lzo_uint new_len;
/* We want to compress the data block at 'in' with length 'IN_LEN' to
* the block at 'out'. Because the input block may be incompressible,
* we must provide a little more output space in case that compression
* is not possible.
*/
unsigned char __LZO_MMODEL in[size];
unsigned char __LZO_MMODEL out[size + size/16 + 64 + 3];

static bool isInit = false;
if (!isInit)
{
if (lzo_init() != LZO_E_OK)
{
printf("internal error - lzo_init() failed !!!\n");
return 0;
}
isInit = true;
}

/* Compress with LZO1X-1. */
r = lzo1x_1_compress(data,size,out,&out_len,wrkmem);
assert(r == LZO_E_OK);
printf("compressed %lu bytes into %lu bytes\n",
(unsigned long) size, (unsigned long) out_len);

/* check for an incompressible block */
if (out_len >= size)
{
printf("This block contains incompressible data.\n");
return 0;
}

/* Decompress. */
new_len = size;
r = lzo1x_decompress(out,out_len,in,&new_len,NULL);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be nice to have another target that tried to decompress data. Right now lzo1x_decompress is not decompressing anything invalid.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. @markus-oberhumer What do you think of adding lzo to oss fuzz?

Would it be better to move this and future test harnesses to lzo repo? Currently this PR picks up an lzo release. Would it be better to fuzz the current development commit instead? I couldn't find a public repository for lzo unfortunately.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Markus: we prefer to have fuzz targets upstream (less likely to break)

Copy link
Contributor Author

@bshastry bshastry Oct 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jonathanmetzman I added a decompress only target in the source branch of this PR. Looking forward to feedback.

At the moment, there is a shallow heap-buffer overrun (READ) like so for a 1 byte compressed data:

READ of size 8 at 0x6020000000d1 thread T0                                                             
SCARINESS: 23 (8-byte-read-heap-buffer-overflow)                                           
    #0 0x5bdcce in lzo1x_decompress /src/lzo-2.10/src/lzo1x_d.ch:120:13

assert(r == LZO_E_OK && new_len == size);
printf("decompressed %lu bytes back into %lu bytes\n",
(unsigned long) out_len, (unsigned long) size);
return 0;
}
2 changes: 2 additions & 0 deletions projects/lzo/lzo_compress_target.options
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[libfuzzer]
close_fd_mask = 3
93 changes: 93 additions & 0 deletions projects/lzo/lzo_decompress_target.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
# Copyright 2018 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
################################################################################
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
#include "lzo1b.h"
#include "lzo1c.h"
#include "lzo1f.h"
#include "lzo1x.h"
#include "lzo1y.h"
#include "lzo1z.h"
#include "lzo2a.h"

/* Work-memory needed for compression. Allocate memory in units
* of 'lzo_align_t' (instead of 'char') to make sure it is properly aligned.
*/
#define HEAP_ALLOC(var,size) \
lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) ]

static HEAP_ALLOC(wrkmem, LZO1X_1_MEM_COMPRESS);

typedef int (*decompress_function)( const lzo_bytep, lzo_uint ,
lzo_bytep, lzo_uintp,
lzo_voidp );

#define NUM_DECOMP 7

static decompress_function funcArr[NUM_DECOMP] =
{
&lzo1b_decompress_safe,
&lzo1c_decompress_safe,
&lzo1f_decompress_safe,
&lzo1x_decompress_safe,
&lzo1y_decompress_safe,
&lzo1z_decompress_safe,
&lzo2a_decompress_safe
};

extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
int r;
lzo_uint new_len;
if (size < 2){
return 0;
}
/* We want to compress the data block at 'in' with length 'IN_LEN' to
* the block at 'out'. Because the input block may be incompressible,
* we must provide a little more output space in case that compression
* is not possible.
*/
unsigned char __LZO_MMODEL out[size];

static bool isInit = false;
if (!isInit)
{
if (lzo_init() != LZO_E_OK)
{
printf("internal error - lzo_init() failed !!!\n");
return 0;
}
isInit = true;
}

/* Decompress. */
int idx = data[0] % NUM_DECOMP;
new_len = size;
r = (*funcArr[idx])(&data[1],size-1,out,&new_len,NULL);
if (r != LZO_E_OK)
{
printf("error thrown by lzo1x_decompress_safe: %d\n", r);
}
printf("decompressed %lu bytes back into %lu bytes\n",
(unsigned long) size, (unsigned long) new_len);
return 0;
}
2 changes: 2 additions & 0 deletions projects/lzo/lzo_decompress_target.options
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[libfuzzer]
close_fd_mask = 3
Binary file added projects/lzo/lzo_decompress_target_seeds/seed.lzo
Binary file not shown.
8 changes: 8 additions & 0 deletions projects/lzo/project.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
homepage: "http://www.oberhumer.com"
primary_contact: "info@oberhumer.com"
auto_ccs:
- "bshas3@gmail.com"
sanitizers:
- address
- memory
- undefined