// 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 #include #include #include 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; }