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

.github: upload failing inputs from fuzzer runs #248

Merged
merged 3 commits into from
Jun 2, 2024
Merged
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
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
Loading