mirror of https://github.com/google/oss-fuzz.git
[PostgreSQL] Add new protocol fuzzer (#4431)
* Add new protocol fuzzer * Fixed fuzzer * Removed tar
This commit is contained in:
parent
ac56d80070
commit
e0f8bad47b
|
@ -25,4 +25,4 @@ WORKDIR postgresql
|
|||
RUN mkdir bld
|
||||
|
||||
COPY fuzzer $SRC/fuzzer
|
||||
COPY build.sh $SRC/
|
||||
COPY build.sh add_fuzzers.diff $SRC/
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
|
||||
index c9424f167c..aa2897ec63 100644
|
||||
--- a/src/backend/tcop/postgres.c
|
||||
+++ b/src/backend/tcop/postgres.c
|
||||
@@ -101,6 +101,10 @@ int max_stack_depth = 100;
|
||||
/* wait N seconds to allow attach from a debugger */
|
||||
int PostAuthDelay = 0;
|
||||
|
||||
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
+bool fuzzer_first_run = true;
|
||||
+#endif
|
||||
+
|
||||
|
||||
|
||||
/* ----------------
|
||||
@@ -505,11 +509,14 @@ static int
|
||||
ReadCommand(StringInfo inBuf)
|
||||
{
|
||||
int result;
|
||||
-
|
||||
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
+ result = SocketBackend(inBuf);
|
||||
+#else
|
||||
if (whereToSendOutput == DestRemote)
|
||||
result = SocketBackend(inBuf);
|
||||
else
|
||||
result = InteractiveBackend(inBuf);
|
||||
+#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -3784,6 +3791,10 @@ PostgresMain(int argc, char *argv[],
|
||||
volatile bool send_ready_for_query = true;
|
||||
bool disable_idle_in_transaction_timeout = false;
|
||||
|
||||
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
+ if(fuzzer_first_run)
|
||||
+ {
|
||||
+#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
|
||||
/* Initialize startup process environment if necessary. */
|
||||
if (!IsUnderPostmaster)
|
||||
InitStandaloneProcess(argv[0]);
|
||||
@@ -4151,6 +4162,11 @@ PostgresMain(int argc, char *argv[],
|
||||
if (!ignore_till_sync)
|
||||
send_ready_for_query = true; /* initially, or after error */
|
||||
|
||||
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
+ fuzzer_first_run=false;
|
||||
+ }
|
||||
+#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
|
||||
+
|
||||
/*
|
||||
* Non-error queries loop here.
|
||||
*/
|
||||
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
|
||||
index d0b368530e..02a3e9066e 100644
|
||||
--- a/src/backend/utils/error/elog.c
|
||||
+++ b/src/backend/utils/error/elog.c
|
||||
@@ -513,7 +513,9 @@ errfinish(const char *filename, int lineno, const char *funcname)
|
||||
pq_endcopyout(true);
|
||||
|
||||
/* Emit the message to the right places */
|
||||
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
EmitErrorReport();
|
||||
+#endif
|
||||
|
||||
/* Now free up subsidiary data attached to stack entry, and release it */
|
||||
if (edata->message)
|
|
@ -15,6 +15,7 @@
|
|||
#
|
||||
################################################################################
|
||||
cp -r $SRC/fuzzer src/backend/
|
||||
git apply ../add_fuzzers.diff
|
||||
|
||||
useradd fuzzuser
|
||||
chown -R fuzzuser .
|
||||
|
|
|
@ -37,15 +37,17 @@ OBJS_FUZZERS = $(filter-out ../main/objfiles.txt, $(OBJS))
|
|||
createdb: dbfuzz
|
||||
|
||||
fuzzer: simple_query_fuzzer \
|
||||
json_parser_fuzzer
|
||||
|
||||
json_parser_fuzzer \
|
||||
protocol_fuzzer
|
||||
|
||||
simple_query_fuzzer json_parser_fuzzer: %: %.o fuzzer_initialize.o $(OBJS_FUZZERS)
|
||||
$(CXX) $(CFLAGS) $(call expand_subsys,$^) -o $@ $(LIB_FUZZING_ENGINE)
|
||||
|
||||
simple_query_fuzzer.o json_parser_fuzzer.o fuzzer_initialize.o: %.o: %.c
|
||||
simple_query_fuzzer.o json_parser_fuzzer.o protocol_fuzzer.o fuzzer_initialize.o: %.o: %.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $^
|
||||
|
||||
protocol_fuzzer: %: %.o $(OBJS_FUZZERS)
|
||||
$(CXX) $(CFLAGS) $(call expand_subsys,$^) -o $@ $(LIB_FUZZING_ENGINE) -Wl,--wrap=exit -Wl,--wrap=pq_getbyte
|
||||
|
||||
dbfuzz: dbfuzz.o | submake-libpgport temp-install
|
||||
$(CC) $(CFLAGS) $^ $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@ \
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
// Copyright 2020 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 "postgres.h"
|
||||
|
||||
#include "access/xlog.h"
|
||||
#include "access/xact.h"
|
||||
#include "common/ip.h"
|
||||
#include "common/username.h"
|
||||
#include "executor/spi.h"
|
||||
#include "jit/jit.h"
|
||||
#include "libpq/auth.h"
|
||||
#include "libpq/libpq.h"
|
||||
#include "libpq/pqsignal.h"
|
||||
#include "miscadmin.h"
|
||||
#include "optimizer/optimizer.h"
|
||||
#include "parser/analyze.h"
|
||||
#include "parser/parser.h"
|
||||
#include "storage/proc.h"
|
||||
#include "tcop/tcopprot.h"
|
||||
#include "utils/datetime.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "utils/memdebug.h"
|
||||
#include "utils/pidfile.h"
|
||||
#include "utils/portal.h"
|
||||
#include "utils/snapmgr.h"
|
||||
#include "utils/ps_status.h"
|
||||
#include "utils/timeout.h"
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <libgen.h>
|
||||
|
||||
const char *progname = "progname";
|
||||
static sigjmp_buf postgre_exit;
|
||||
static bool postgre_started;
|
||||
static char *buffer;
|
||||
static size_t buffersize;
|
||||
static char *bufferpointer;
|
||||
static char *av[6];
|
||||
|
||||
int LLVMFuzzerInitialize(int *argc, char ***argv) {
|
||||
char *exe_path = (*argv)[0];
|
||||
//dirname() can modify its argument
|
||||
char *exe_path_copy = strdup(exe_path);
|
||||
char *dir = dirname(exe_path_copy);
|
||||
chdir(dir);
|
||||
free(exe_path_copy);
|
||||
|
||||
av[0] = "tmp_install/usr/local/pgsql/bin/postgres";
|
||||
av[1] = "--single";
|
||||
av[2] = "-D/tmp/protocol_db/data";
|
||||
av[3] = "-F";
|
||||
av[4] = "-k\"/tmp\"";
|
||||
av[5] = NULL;
|
||||
|
||||
system("rm -rf /tmp/protocol_db; mkdir /tmp/protocol_db; cp -r data /tmp/protocol_db");
|
||||
system("cp -r tmp_install /tmp/");
|
||||
|
||||
MemoryContextInit();
|
||||
if(!sigsetjmp(postgre_exit, 0)){
|
||||
postgre_started = true;
|
||||
PostgresMain(5, av, "dbfuzz", "fuzzuser");
|
||||
}
|
||||
pq_endmsgread();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __wrap_exit(int status){
|
||||
if(postgre_started)
|
||||
siglongjmp(postgre_exit, 1);
|
||||
else
|
||||
__real_exit(status);
|
||||
}
|
||||
|
||||
int __wrap_pq_getbyte(void){
|
||||
if(!buffersize) return EOF;
|
||||
unsigned char cur = buffer[0];
|
||||
bufferpointer++; buffersize--;
|
||||
return cur;
|
||||
}
|
||||
|
||||
/*
|
||||
** Main entry point. The fuzzer invokes this function with each
|
||||
** fuzzed input.
|
||||
*/
|
||||
int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
buffersize = size;
|
||||
buffer = (char *) calloc(size, sizeof(char));
|
||||
bufferpointer = buffer;
|
||||
memcpy(buffer, data, size);
|
||||
|
||||
if(!sigsetjmp(postgre_exit, 0)){
|
||||
postgre_started = true;
|
||||
PostgresMain(5, av, "dbfuzz", "fuzzuser");
|
||||
}
|
||||
pq_endmsgread();
|
||||
postgre_started = false;
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue