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

Added fuzzer and oss-fuzz build-script #44

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions libmspack/test/fuzzing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
This directory includes a fuzzing function that could be linked into Google's OSS-Fuzz project

https://google.github.io/oss-fuzz/

This integration is not yet complete, see:
* https://github.com/kyz/libmspack/pull/44
* https://github.com/google/oss-fuzz/pull/5085
111 changes: 111 additions & 0 deletions libmspack/test/fuzzing/extract_fuzzer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/* This file is part of libmspack.
* (C) 2021 Stuart Caie.
*
* libmspack is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License (LGPL) version 2.1
*
* For further details, see the file COPYING.LIB distributed with libmspack
*/

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <mspack.h>

/* mspack_system implementation which reads memory and writes nothing */
struct mem_buf {
const uint8_t *data;
size_t length;
};
struct mem_file {
char *data;
size_t length, posn;
};
static struct mspack_file *m_open(struct mspack_system *self, const char *filename, int mode) {
struct mem_buf *fn = (struct mem_buf *) filename;
struct mem_file *fh;
if ((mode != MSPACK_SYS_OPEN_READ && mode != MSPACK_SYS_OPEN_WRITE) ||
(mode == MSPACK_SYS_OPEN_READ && fn == NULL)) return NULL;

if ((fh = (struct mem_file *) malloc(sizeof(struct mem_file)))) {
if (mode == MSPACK_SYS_OPEN_READ) {
fh->data = (char *) fn->data;
fh->length = fn->length;
}
else {
fh->data = NULL;
fh->length = 0;
}
fh->posn = 0;
return (struct mspack_file *) fh;
}
return NULL;
}
static void m_close(struct mspack_file *file) {
free(file);
}
static int m_read(struct mspack_file *file, void *buffer, int bytes) {
struct mem_file *fh = (struct mem_file *) file;
int avail;
if (!fh || !buffer || bytes < 0) return -1;
avail = fh->length - fh->posn;
if (bytes > avail) bytes = avail;
if (bytes > 0) memcpy(buffer, &fh->data[fh->posn], bytes);
fh->posn += bytes;
return bytes;
}
static int m_write(struct mspack_file *file, void *buffer, int bytes) {
return (!file || !buffer || bytes < 0) ? -1 : bytes;
}
static int m_seek(struct mspack_file *file, off_t offset, int mode) {
struct mem_file *fh = (struct mem_file *) file;
if (!fh) return 1;
switch (mode) {
case MSPACK_SYS_SEEK_START: break;
case MSPACK_SYS_SEEK_CUR: offset += (off_t) fh->posn; break;
case MSPACK_SYS_SEEK_END: offset += (off_t) fh->length; break;
default: return 1;
}
if ((offset < 0) || (offset > (off_t) fh->length)) return 1;
fh->posn = (size_t) offset;
return 0;
}
static off_t m_tell(struct mspack_file *file) {
struct mem_file *fh = (struct mem_file *) file;
return (fh) ? (off_t) fh->posn : -1;
}
static void m_msg(struct mspack_file *file, const char *format, ...) {
}
static void *m_alloc(struct mspack_system *self, size_t bytes) {
return malloc(bytes);
}
static void m_free(void *buffer) {
free(buffer);
}
static void m_copy(void *src, void *dest, size_t bytes) {
memcpy(dest, src, bytes);
}
static struct mspack_system mem_system = {
&m_open, &m_close, &m_read, &m_write, &m_seek, &m_tell,
&m_msg, &m_alloc, &m_free, &m_copy, NULL
};

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
struct mscab_decompressor *cabd;
struct mscabd_cabinet *cab;
struct mscabd_file *file;
struct mem_buf source = { data, size };

if ((cabd = mspack_create_cab_decompressor(&mem_system))) {
if ((cab = cabd->open(cabd, (char *) &source))) {
/* attempt to extract all files (to nowhere) */
for (file = cab->files; file; file = file->next) {
cabd->extract(cabd, file, NULL);
}
cabd->close(cabd, cab);
}
}
mspack_destroy_cab_decompressor(cabd);
return 0;
}
12 changes: 12 additions & 0 deletions libmspack/test/fuzzing/oss_fuzz_build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash -eu

cd libmspack
./autogen.sh
./configure
make -j$(nproc)

find . -name "*.o" -exec ar rcs fuzz_lib.a {} \;
$CXX $CXXFLAGS -I./mspack -c $SRC/extract_fuzzer.c -o extract_fuzzer.o
$CXX $CXXFLAGS $LIB_FUZZING_ENGINE extract_fuzzer.o -o $OUT/extract_fuzzer fuzz_lib.a

zip $OUT/extract_fuzzer_seed_corpus.zip $SRC/libmspack/libmspack/test/test_files/cabd/partial_shortfile1.cab