mirror of https://github.com/google/oss-fuzz.git
git: Combine multiple git command fuzzer to one (#8579)
List of git commands covered GIT_ADD GIT_BRANCH GIT_COMMIT GIT_CONFIG GIT_DIFF GIT_DIFF_FILES GIT_DIFF_INDEX GIT_DIFF_TREE GIT_LS_FILES GIT_LS_TREE GIT_MV GIT_RERERE GIT_STATUS GIT_VERSION
This commit is contained in:
parent
551ad63712
commit
39a4c95af3
|
@ -1,24 +1,25 @@
|
|||
diff --git a/Makefile b/Makefile
|
||||
index 924b864ae8..bd68d0f05a 100644
|
||||
index 924b864ae8..3f0e004a5e 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -689,9 +689,12 @@ SCRIPTS = $(SCRIPT_SH_GEN) \
|
||||
|
||||
@@ -689,9 +689,13 @@ SCRIPTS = $(SCRIPT_SH_GEN) \
|
||||
|
||||
ETAGS_TARGET = TAGS
|
||||
|
||||
|
||||
-FUZZ_OBJS += fuzz-commit-graph.o
|
||||
-FUZZ_OBJS += fuzz-pack-headers.o
|
||||
-FUZZ_OBJS += fuzz-pack-idx.o
|
||||
+FUZZ_OBJS += oss-fuzz/fuzz-commit-graph.o
|
||||
+FUZZ_OBJS += oss-fuzz/fuzz-pack-headers.o
|
||||
+FUZZ_OBJS += oss-fuzz/fuzz-pack-idx.o
|
||||
+FUZZ_OBJS += oss-fuzz/fuzz-command.o
|
||||
+FUZZ_OBJS += oss-fuzz/fuzz-cmd-status.o
|
||||
+FUZZ_OBJS += oss-fuzz/fuzz-cmd-version.o
|
||||
+FUZZ_OBJS += oss-fuzz/fuzz-cmd-diff.o
|
||||
.PHONY: fuzz-objs
|
||||
fuzz-objs: $(FUZZ_OBJS)
|
||||
|
||||
@@ -1012,6 +1015,7 @@ LIB_OBJS += oid-array.o
|
||||
|
||||
@@ -1012,6 +1016,7 @@ LIB_OBJS += oid-array.o
|
||||
LIB_OBJS += oidmap.o
|
||||
LIB_OBJS += oidset.o
|
||||
LIB_OBJS += oidtree.o
|
||||
|
|
|
@ -22,6 +22,7 @@ make -j$(nproc) CC=$CC CXX=$CXX CFLAGS="$CFLAGS" \
|
|||
|
||||
FUZZERS="fuzz-pack-headers fuzz-pack-idx fuzz-commit-graph"
|
||||
FUZZERS="$FUZZERS fuzz-cmd-status fuzz-cmd-version fuzz-cmd-diff"
|
||||
FUZZERS="$FUZZERS fuzz-command"
|
||||
|
||||
# copy fuzzers
|
||||
for fuzzer in $FUZZERS ; do
|
||||
|
|
|
@ -131,7 +131,8 @@ void generate_commit_in_branch(char *data, int size, char *branch_name)
|
|||
strbuf_addf(&push_cmd, "git push origin %s", branch_name);
|
||||
|
||||
if (system("git add TEMP-*-TEMP") ||
|
||||
system("git commit -m\"New Commit\""))
|
||||
system("git commit -m\"New Commit\"") ||
|
||||
system(push_cmd.buf))
|
||||
{
|
||||
// Just skip the commit if fails
|
||||
strbuf_release(&push_cmd);
|
||||
|
|
|
@ -15,6 +15,23 @@ limitations under the License.
|
|||
#define HASH_SIZE 20
|
||||
#define HASH_HEX_SIZE 40
|
||||
#define INT_SIZE 4
|
||||
#define GIT_COMMAND_COUNT 12
|
||||
|
||||
typedef enum git_command {
|
||||
GIT_STATUS = 0,
|
||||
GIT_ADD_COMMIT = 1,
|
||||
GIT_VERSION = 2,
|
||||
GIT_CONFIG_RERERE = 3,
|
||||
GIT_DIFF = 4,
|
||||
GIT_DIFF_FILES = 5,
|
||||
GIT_DIFF_TREE = 6,
|
||||
GIT_DIFF_INDEX = 7,
|
||||
GIT_BRANCH = 8,
|
||||
GIT_MV = 9,
|
||||
GIT_LS_FILES = 10,
|
||||
GIT_LS_TREE = 11
|
||||
} git_command_t;
|
||||
|
||||
|
||||
int randomize_git_file(char *dir, char *name, char *data, int size);
|
||||
void randomize_git_files(char *dir, char *name_set[],
|
||||
|
|
|
@ -0,0 +1,307 @@
|
|||
/* Copyright 2022 Google LLC
|
||||
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 "builtin.h"
|
||||
#include "repository.h"
|
||||
#include "fuzz-cmd-base.h"
|
||||
|
||||
int cmd_add(int argc, const char **argv, const char *prefix);
|
||||
int cmd_branch(int argc, const char **argv, const char *prefix);
|
||||
int cmd_commit(int argc, const char **argv, const char *prefix);
|
||||
int cmd_config(int argc, const char **argv, const char *prefix);
|
||||
int cmd_diff(int argc, const char **argv, const char *prefix);
|
||||
int cmd_diff_files(int argc, const char **argv, const char *prefix);
|
||||
int cmd_diff_index(int argc, const char **argv, const char *prefix);
|
||||
int cmd_diff_tree(int argc, const char **argv, const char *prefix);
|
||||
int cmd_ls_files(int argc, const char **argv, const char *prefix);
|
||||
int cmd_ls_tree(int argc, const char **argv, const char *prefix);
|
||||
int cmd_mv(int argc, const char **argv, const char *prefix);
|
||||
int cmd_rerere(int argc, const char **argv, const char *prefix);
|
||||
int cmd_status(int argc, const char **argv, const char *prefix);
|
||||
int cmd_version(int argc, const char **argv, const char *prefix);
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
int i;
|
||||
int argc;
|
||||
int no_of_commit;
|
||||
int max_commit_count;
|
||||
char *argv[6];
|
||||
char *data_chunk;
|
||||
char *basedir = "./.git";
|
||||
git_command_t choice;
|
||||
struct strbuf name = STRBUF_INIT;
|
||||
|
||||
/*
|
||||
* Initialize the repository
|
||||
*/
|
||||
initialize_the_repository();
|
||||
|
||||
/*
|
||||
* End this round of fuzzing if the data is not large enough
|
||||
*/
|
||||
if (size <= (HASH_HEX_SIZE * 4 + HASH_SIZE + INT_SIZE * 2))
|
||||
{
|
||||
repo_clear(the_repository);
|
||||
return 0;
|
||||
}
|
||||
|
||||
reset_git_folder();
|
||||
|
||||
/*
|
||||
* Generate random commit
|
||||
*/
|
||||
max_commit_count = get_max_commit_count(size, 0,
|
||||
HASH_HEX_SIZE * 2 + HASH_SIZE + INT_SIZE * 2);
|
||||
no_of_commit = (*((int *)data)) % max_commit_count + 1;
|
||||
data += 4;
|
||||
size -= 4;
|
||||
|
||||
choice = (*((int *)data)) % GIT_COMMAND_COUNT;
|
||||
data += 4;
|
||||
size -= 4;
|
||||
|
||||
data_chunk = xmallocz_gently(HASH_HEX_SIZE);
|
||||
|
||||
if (!data_chunk)
|
||||
{
|
||||
repo_clear(the_repository);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < no_of_commit; i++)
|
||||
{
|
||||
memcpy(data_chunk, data, HASH_HEX_SIZE);
|
||||
generate_commit(data_chunk, HASH_SIZE);
|
||||
data += HASH_HEX_SIZE;
|
||||
size -= HASH_HEX_SIZE;
|
||||
}
|
||||
|
||||
free(data_chunk);
|
||||
|
||||
/*
|
||||
* Final preparing of the repository settings
|
||||
*/
|
||||
repo_clear(the_repository);
|
||||
if (repo_init(the_repository, basedir, "."))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Alter content of TEMP_1 and TEMP_2
|
||||
*/
|
||||
data_chunk = xmallocz_gently(HASH_SIZE);
|
||||
memcpy(data_chunk, data, HASH_SIZE);
|
||||
randomize_git_file(".", "TEMP_1", data_chunk, HASH_SIZE);
|
||||
memcpy(data_chunk, data + HASH_SIZE, HASH_SIZE);
|
||||
randomize_git_file(".", "TEMP_2", data_chunk, HASH_SIZE);
|
||||
data += (HASH_SIZE * 2);
|
||||
size -= (HASH_SIZE * 2);
|
||||
free(data_chunk);
|
||||
|
||||
/*
|
||||
* Generate random name for different usage
|
||||
*/
|
||||
data_chunk = xmallocz_gently(HASH_SIZE);
|
||||
memcpy(data_chunk, data, HASH_SIZE);
|
||||
strbuf_addf(&name, "name-%s-name", hash_to_hex((unsigned char *)data_chunk));
|
||||
data += HASH_SIZE;
|
||||
size -= HASH_SIZE;
|
||||
free(data_chunk);
|
||||
|
||||
switch(choice) {
|
||||
case GIT_STATUS: default:
|
||||
argv[0] = "status";
|
||||
argv[1] = "-v";
|
||||
argv[2] = NULL;
|
||||
cmd_status(2, (const char **)argv, (const char *)"");
|
||||
|
||||
break;
|
||||
|
||||
case GIT_ADD_COMMIT:
|
||||
argv[0] = "add";
|
||||
argv[1] = "-u";
|
||||
argv[2] = NULL;
|
||||
cmd_add(2, (const char **)argv, (const char *)"");
|
||||
|
||||
argv[0] = "commit";
|
||||
argv[1] = "-m";
|
||||
argv[2] = "\"New Commit\"";
|
||||
argv[3] = NULL;
|
||||
cmd_commit(3, (const char **)argv, (const char *)"");
|
||||
|
||||
break;
|
||||
|
||||
case GIT_VERSION:
|
||||
argv[0] = "version";
|
||||
argv[1] = NULL;
|
||||
cmd_version(1, (const char **)argv, (const char *)"");
|
||||
|
||||
argv[1] = "--build-options";
|
||||
argv[2] = NULL;
|
||||
cmd_version(2, (const char **)argv, (const char *)"");
|
||||
|
||||
break;
|
||||
|
||||
case GIT_CONFIG_RERERE:
|
||||
argv[0] = "config";
|
||||
argv[1] = "--global";
|
||||
argv[2] = "rerere.enabled";
|
||||
argv[3] = "true";
|
||||
argv[4] = NULL;
|
||||
cmd_config(4, (const char **)argv, (const char *)"");
|
||||
|
||||
argv[0] = "rerere";
|
||||
argv[1] = NULL;
|
||||
cmd_rerere(1, (const char **)argv, (const char *)"");
|
||||
|
||||
argv[1] = "clear";
|
||||
argv[2] = NULL;
|
||||
cmd_rerere(2, (const char **)argv, (const char *)"");
|
||||
|
||||
argv[1] = "diff";
|
||||
cmd_rerere(2, (const char **)argv, (const char *)"");
|
||||
|
||||
argv[1] = "remaining";
|
||||
cmd_rerere(2, (const char **)argv, (const char *)"");
|
||||
|
||||
argv[1] = "status";
|
||||
cmd_rerere(2, (const char **)argv, (const char *)"");
|
||||
|
||||
argv[1] = "gc";
|
||||
cmd_rerere(2, (const char **)argv, (const char *)"");
|
||||
|
||||
break;
|
||||
|
||||
case GIT_DIFF:
|
||||
argv[0] = "diff";
|
||||
argv[1] = NULL;
|
||||
cmd_diff(1, (const char **)argv, (const char *)"");
|
||||
|
||||
argv[1] = "TEMP_1";
|
||||
argv[2] = NULL;
|
||||
cmd_diff(2, (const char **)argv, (const char *)"");
|
||||
|
||||
argv[2] = "TEMP_2";
|
||||
argv[3] = NULL;
|
||||
cmd_diff(3, (const char **)argv, (const char *)"");
|
||||
|
||||
break;
|
||||
|
||||
case GIT_DIFF_FILES:
|
||||
argv[0] = "diff-files";
|
||||
argv[1] = NULL;
|
||||
cmd_diff_files(1, (const char **)argv, (const char *)"");
|
||||
|
||||
argv[1] = "TEMP_1";
|
||||
argv[2] = NULL;
|
||||
cmd_diff_files(2, (const char **)argv, (const char *)"");
|
||||
|
||||
argv[2] = "TEMP_2";
|
||||
argv[3] = NULL;
|
||||
cmd_diff_files(3, (const char **)argv, (const char *)"");
|
||||
|
||||
break;
|
||||
|
||||
case GIT_DIFF_TREE:
|
||||
argv[0] = "diff-tree";
|
||||
argv[1] = "master";
|
||||
argv[2] = "--";
|
||||
argv[3] = NULL;
|
||||
cmd_diff_tree(3, (const char **)argv, (const char *)"");
|
||||
|
||||
break;
|
||||
|
||||
case GIT_DIFF_INDEX:
|
||||
argv[0] = "diff-index";
|
||||
argv[1] = "master";
|
||||
argv[2] = "--";
|
||||
argv[3] = NULL;
|
||||
cmd_diff_index(3, (const char **)argv, (const char *)"");
|
||||
|
||||
argv[2] = "--";
|
||||
argv[3] = "TEMP_1";
|
||||
argv[4] = NULL;
|
||||
cmd_diff_index(4, (const char **)argv, (const char *)"");
|
||||
|
||||
argv[2] = "--";
|
||||
argv[3] = "TEMP_1";
|
||||
argv[4] = "TEMP_2";
|
||||
argv[5] = NULL;
|
||||
cmd_diff_index(5, (const char **)argv, (const char *)"");
|
||||
|
||||
break;
|
||||
|
||||
case GIT_BRANCH:
|
||||
argv[0] = "branch";
|
||||
argv[1] = name.buf;
|
||||
argv[2] = NULL;
|
||||
cmd_branch(2, (const char **)argv, (const char *)"");
|
||||
|
||||
argv[1] = "-d";
|
||||
argv[2] = name.buf;
|
||||
argv[3] = NULL;
|
||||
cmd_branch(3, (const char **)argv, (const char *)"");
|
||||
|
||||
break;
|
||||
|
||||
case GIT_MV:
|
||||
argv[0] = "mv";
|
||||
argv[1] = "-k";
|
||||
argv[2] = "TEMP_1";
|
||||
argv[3] = name.buf;
|
||||
argv[4] = NULL;
|
||||
cmd_mv(4, (const char **)argv, (const char *)"");
|
||||
|
||||
argv[1] = "-k";
|
||||
argv[2] = name.buf;
|
||||
argv[3] = "TEMP_1";
|
||||
argv[4] = NULL;
|
||||
cmd_mv(4, (const char **)argv, (const char *)"");
|
||||
|
||||
break;
|
||||
|
||||
case GIT_LS_FILES:
|
||||
argv[0] = "ls-files";
|
||||
argv[1] = NULL;
|
||||
cmd_ls_files(1, (const char **)argv, (const char *)"");
|
||||
|
||||
argv[1] = "TEMP";
|
||||
argv[2] = NULL;
|
||||
cmd_ls_files(2, (const char **)argv, (const char *)"");
|
||||
|
||||
argv[1] = "-m";
|
||||
argv[2] = NULL;
|
||||
cmd_ls_files(2, (const char **)argv, (const char *)"");
|
||||
|
||||
argv[1] = name.buf;
|
||||
argv[2] = NULL;
|
||||
cmd_ls_files(2, (const char **)argv, (const char *)"");
|
||||
|
||||
break;
|
||||
|
||||
case GIT_LS_TREE:
|
||||
argv[0] = "ls-tree";
|
||||
argv[1] = "master";
|
||||
argv[2] = NULL;
|
||||
cmd_ls_tree(2, (const char **)argv, (const char *)"");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
strbuf_release(&name);
|
||||
repo_clear(the_repository);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue