Skip to content

Commit

Permalink
Merge pull request #248 from Gottox/chores/upload-fuzzer-artifacts
Browse files Browse the repository at this point in the history
.github: upload failing inputs from fuzzer runs
  • Loading branch information
Gottox committed Jun 2, 2024
2 parents 9d630a7 + 95609b4 commit 7146b96
Show file tree
Hide file tree
Showing 57 changed files with 323 additions and 1,533 deletions.
8 changes: 8 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ jobs:
runs-on: ubuntu-latest
container:
image: gottox/sqsh-build:x86_64
volumes:
- /tmp/build:/tmp/build
steps:
- uses: actions/checkout@v4
- name: configure
Expand All @@ -103,6 +105,12 @@ jobs:
- name: fuzzer
run: |
ninja -C /tmp/build test
- name: Upload Failing Inputs
uses: actions/upload-artifact@v4
if: failure()
with:
name: failing-inputs
path: /tmp/build/fuzzer/inputs

build:
needs:
Expand Down
Binary file added fuzzer/inputs/extract.fuzz_crash_1
Binary file not shown.
Binary file added fuzzer/inputs/extract.fuzz_crash_10
Binary file not shown.
Binary file added fuzzer/inputs/extract.fuzz_crash_11
Binary file not shown.
Binary file added fuzzer/inputs/extract.fuzz_crash_12
Binary file not shown.
Binary file added fuzzer/inputs/extract.fuzz_crash_13
Binary file not shown.
Binary file added fuzzer/inputs/extract.fuzz_crash_14
Binary file not shown.
Binary file added fuzzer/inputs/extract.fuzz_crash_15
Binary file not shown.
Binary file added fuzzer/inputs/extract.fuzz_crash_16
Binary file not shown.
Binary file added fuzzer/inputs/extract.fuzz_crash_17
Binary file not shown.
Binary file added fuzzer/inputs/extract.fuzz_crash_18
Binary file not shown.
Binary file added fuzzer/inputs/extract.fuzz_crash_19
Binary file not shown.
Binary file added fuzzer/inputs/extract.fuzz_crash_2
Binary file not shown.
Binary file added fuzzer/inputs/extract.fuzz_crash_20
Binary file not shown.
Binary file added fuzzer/inputs/extract.fuzz_crash_21
Binary file not shown.
Binary file added fuzzer/inputs/extract.fuzz_crash_3
Binary file not shown.
Binary file added fuzzer/inputs/extract.fuzz_crash_4
Binary file not shown.
Binary file added fuzzer/inputs/extract.fuzz_crash_5
Binary file not shown.
Binary file added fuzzer/inputs/extract.fuzz_crash_6
Binary file not shown.
Binary file added fuzzer/inputs/extract.fuzz_crash_7
Binary file not shown.
Binary file added fuzzer/inputs/extract.fuzz_crash_8
Binary file not shown.
Binary file added fuzzer/inputs/extract.fuzz_crash_9
Binary file not shown.
Binary file added fuzzer/inputs/extract.fuzz_leak_1
Binary file not shown.
Binary file added fuzzer/inputs/extract.fuzz_oom_1
Binary file not shown.
13 changes: 11 additions & 2 deletions fuzzer/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,26 @@ fuzzer = executable(
link_with: libsqsh.get_static_lib(),
)

rundir_tgt = custom_target(
'fuzzer_inputs',
output: 'inputs',
command: [mkdir, '-p', '@OUTPUT@'],
)

test(
'simple_fuzzer',
fuzzer,
depends: corpus_tgt,
workdir: rundir_tgt.full_path(),
is_parallel: false,
depends: [corpus_tgt, rundir_tgt],
args: [
corpus_tgt.full_path(),
source_corpus,
'-error_exitcode=1',
'-timeout_exitcode=1',
'-timeout=3',
'-timeout=10',
'-rss_limit_mb=0',
'-malloc_limit_mb=10',
'-max_total_time=@0@'.format(get_option('fuzzer_timeout')),
],
timeout: 10 + get_option('fuzzer_timeout'),
Expand Down
2 changes: 1 addition & 1 deletion libsqsh/include/sqsh_archive_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ struct SqshInodeMap {
*/
const struct SqshInodeMapImpl *impl;
sqsh__mutex_t *mutex;
uint_fast64_t *inode_refs;
struct CxRadixTree inode_refs;
size_t inode_count;
struct SqshExportTable *export_table;
};
Expand Down
47 changes: 33 additions & 14 deletions libsqsh/src/archive/inode_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,8 @@ dyn_map_init(struct SqshInodeMap *map, struct SqshArchive *archive) {
}
pthread_mutex_init(map->mutex, NULL);
map->export_table = NULL;
map->inode_refs = calloc(inode_count, sizeof(uint_fast64_t));
if (map->inode_refs == NULL) {
rv = -SQSH_ERROR_MALLOC_FAILED;
goto out;
}

cx_radix_tree_init(&map->inode_refs, sizeof(uint64_t[256]));
out:
return rv;
}
Expand All @@ -127,7 +124,6 @@ static uint64_t
dyn_map_get(const struct SqshInodeMap *map, uint32_t inode_number, int *err) {
int rv = 0;
uint64_t inode_ref = 0;
uint_fast64_t *inode_refs = map->inode_refs;

if (inode_number == 0 || inode_number - 1 >= map->inode_count) {
rv = -SQSH_ERROR_OUT_OF_BOUNDS;
Expand All @@ -137,7 +133,18 @@ dyn_map_get(const struct SqshInodeMap *map, uint32_t inode_number, int *err) {
if (rv < 0) {
goto out;
}
inode_ref = ~inode_refs[inode_number - 1];

sqsh_index_t index = inode_number - 1;
sqsh_index_t inner_index = index & 0xff;
sqsh_index_t outer_index = index >> 8;

uint_fast64_t *inner_inode_refs =
cx_radix_tree_get(&map->inode_refs, outer_index);
if (inner_inode_refs == NULL) {
rv = -SQSH_ERROR_NO_SUCH_ELEMENT;
goto out;
}
inode_ref = ~inner_inode_refs[inner_index];
if (inode_ref == EMPTY_INODE_REF) {
rv = -SQSH_ERROR_NO_SUCH_ELEMENT;
inode_ref = 0;
Expand All @@ -159,8 +166,6 @@ static int
dyn_map_set(
struct SqshInodeMap *map, uint32_t inode_number, uint64_t inode_ref) {
int rv = 0;
uint64_t old_value;
uint_fast64_t *inode_refs = map->inode_refs;

if (inode_ref == EMPTY_INODE_REF) {
return -SQSH_ERROR_INVALID_ARGUMENT;
Expand All @@ -172,11 +177,25 @@ dyn_map_set(
if (rv < 0) {
return rv;
}
old_value = ~inode_refs[inode_number - 1];
inode_refs[inode_number - 1] = ~inode_ref;
if (old_value != EMPTY_INODE_REF && old_value != inode_ref) {
return -SQSH_ERROR_INODE_MAP_IS_INCONSISTENT;

sqsh_index_t index = inode_number - 1;
sqsh_index_t inner_index = index & 0xff;
sqsh_index_t outer_index = index >> 8;

uint_fast64_t *inner_inode_refs =
cx_radix_tree_get(&map->inode_refs, outer_index);
if (inner_inode_refs == NULL) {
uint64_t new_inner_inode_refs[256] = {0};
new_inner_inode_refs[inner_index] = ~inode_ref;
cx_radix_tree_put(&map->inode_refs, outer_index, new_inner_inode_refs);
} else {
const uint64_t old_value = ~inner_inode_refs[inner_index];
inner_inode_refs[inner_index] = ~inode_ref;
if (old_value != EMPTY_INODE_REF && old_value != inode_ref) {
return -SQSH_ERROR_INODE_MAP_IS_INCONSISTENT;
}
}

rv = sqsh__mutex_unlock(map->mutex);
if (rv < 0) {
return rv;
Expand All @@ -192,7 +211,7 @@ export_table_cleanup(struct SqshInodeMap *map) {

static int
dyn_map_cleanup(struct SqshInodeMap *map) {
free(map->inode_refs);
cx_radix_tree_cleanup(&map->inode_refs);
pthread_mutex_destroy(map->mutex);
free(map->mutex);
return 0;
Expand Down
2 changes: 1 addition & 1 deletion subprojects/cextras.wrap
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[wrap-git]
directory = cextras
revision = 44e59a4d70efdafed930329241b711d2be302cd5
revision = 908ea12a9cdbd1e52ddc45519fc19dc3743a893a
url = https://github.com/Gottox/cextras.git
depth = 1

Expand Down
Binary file added test/fuzzer/fuzz_crash_1
Binary file not shown.
Binary file added test/fuzzer/fuzz_crash_10
Binary file not shown.
Binary file added test/fuzzer/fuzz_crash_11
Binary file not shown.
Binary file added test/fuzzer/fuzz_crash_12
Binary file not shown.
Binary file added test/fuzzer/fuzz_crash_13
Binary file not shown.
Binary file added test/fuzzer/fuzz_crash_14
Binary file not shown.
Binary file added test/fuzzer/fuzz_crash_15
Binary file not shown.
Binary file added test/fuzzer/fuzz_crash_16
Binary file not shown.
Binary file added test/fuzzer/fuzz_crash_17
Binary file not shown.
Binary file added test/fuzzer/fuzz_crash_18
Binary file not shown.
Binary file added test/fuzzer/fuzz_crash_19
Binary file not shown.
Binary file added test/fuzzer/fuzz_crash_2
Binary file not shown.
Binary file added test/fuzzer/fuzz_crash_20
Binary file not shown.
Binary file added test/fuzzer/fuzz_crash_21
Binary file not shown.
Binary file added test/fuzzer/fuzz_crash_22
Binary file not shown.
Binary file added test/fuzzer/fuzz_crash_3
Binary file not shown.
Binary file added test/fuzzer/fuzz_crash_4
Binary file not shown.
Binary file added test/fuzzer/fuzz_crash_5
Binary file not shown.
Binary file added test/fuzzer/fuzz_crash_6
Binary file not shown.
Binary file added test/fuzzer/fuzz_crash_7
Binary file not shown.
Binary file added test/fuzzer/fuzz_crash_8
Binary file not shown.
Binary file added test/fuzzer/fuzz_crash_9
Binary file not shown.
Binary file added test/fuzzer/fuzz_leak_1
Binary file not shown.
59 changes: 59 additions & 0 deletions test/fuzzer/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
fuzzer_repro = files(
'fuzz_crash_1',
'fuzz_crash_10',
'fuzz_crash_11',
'fuzz_crash_12',
'fuzz_crash_13',
'fuzz_crash_14',
'fuzz_crash_15',
'fuzz_crash_16',
'fuzz_crash_17',
'fuzz_crash_18',
'fuzz_crash_19',
'fuzz_crash_2',
'fuzz_crash_20',
'fuzz_crash_21',
'fuzz_crash_22',
'fuzz_crash_3',
'fuzz_crash_4',
'fuzz_crash_5',
'fuzz_crash_6',
'fuzz_crash_7',
'fuzz_crash_8',
'fuzz_crash_9',
'fuzz_leak_1',
)

utest_dep = dependency('utest')

fuzzer_repro_codegen = executable('repro_codegen', 'repro_codegen.c')

fuzzer_repro_tgt = custom_target(
'repro_test',
output: 'repro_test.c',
capture: true,
input: fuzzer_repro,
command: [
fuzzer_repro_codegen,
'@INPUT@',
],
)

fuzzer_src = files(
'../../fuzzer/simple.c',
)
fuzzer_repro_test = executable(
'repro_test',
[fuzzer_repro_tgt, fuzzer_src],
include_directories: [
libsqsh_include,
libsqsh_common_include,
libsqsh_private_include,
libmksqsh_include,
],
link_with: [libsqsh.get_static_lib(), libmksqsh.get_static_lib()],
dependencies: [threads_dep, utest_dep, cextras_dep],

)

test('simple_fuzzer_repro', fuzzer_repro_test)
41 changes: 41 additions & 0 deletions test/fuzzer/repro_codegen.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#include <assert.h>
#include <libgen.h>
#include <stdio.h>

#define HEADER \
"#include <sqsh.h>\n" \
"#include <utest.h>\n" \
"int LLVMFuzzerTestOneInput(char *data, size_t size);"

#define TEST_PRE_FORMAT \
"UTEST(fuzzer_repro, %s) {\n" \
" (void)utest_result;\n" \
" unsigned char input[] = {\n"

#define TEST_POST \
"\n" \
" };\n" \
" LLVMFuzzerTestOneInput((char *)input, sizeof(input));\n" \
"}\n"

#define FOOTER "UTEST_MAIN()"

int
main(int argc, char *argv[]) {
puts("#include <utest.h>\n"
"");
puts(HEADER);
for (int i = 1; i < argc; i++) {
printf(TEST_PRE_FORMAT, basename(argv[i]));
FILE *f = fopen(argv[i], "rb");
assert(f);
int c;
while ((c = fgetc(f)) != EOF) {
printf("0x%02x, ", c);
}
fclose(f);
puts(TEST_POST);
}
puts(FOOTER);
return 0;
}
Loading

0 comments on commit 7146b96

Please sign in to comment.