1 // Copyright 2020 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 ///////////////////////////////////////////////////////////////////////////////
16
17 #include "postgres.h"
18
19 #include "access/xlog.h"
20 #include "access/xact.h"
21 #include "common/ip.h"
22 #include "common/username.h"
23 #include "executor/spi.h"
24 #include "jit/jit.h"
25 #include "libpq/auth.h"
26 #include "libpq/libpq.h"
27 #include "libpq/pqsignal.h"
28 #include "miscadmin.h"
29 #include "optimizer/optimizer.h"
30 #include "parser/analyze.h"
31 #include "parser/parser.h"
32 #include "storage/proc.h"
33 #include "tcop/tcopprot.h"
34 #include "utils/datetime.h"
35 #include "utils/memutils.h"
36 #include "utils/memdebug.h"
37 #include "utils/pidfile.h"
38 #include "utils/portal.h"
39 #include "utils/snapmgr.h"
40 #include "utils/ps_status.h"
41 #include "utils/timeout.h"
42
43 #include <sys/socket.h>
44 #include <sys/types.h>
45 #include <unistd.h>
46 #include <libgen.h>
47
48 const char *progname = "progname";
49 static sigjmp_buf postgre_exit;
50 static bool postgre_started;
51 static char *buffer;
52 static size_t buffersize;
53 static char *bufferpointer;
54 static char *av[6];
55
LLVMFuzzerInitialize(int * argc,char *** argv)56 int LLVMFuzzerInitialize(int *argc, char ***argv) {
57 char *exe_path = (*argv)[0];
58 //dirname() can modify its argument
59 char *exe_path_copy = strdup(exe_path);
60 char *dir = dirname(exe_path_copy);
61 chdir(dir);
62 free(exe_path_copy);
63
64 av[0] = "tmp_install/usr/local/pgsql/bin/postgres";
65 av[1] = "--single";
66 av[2] = "-D/tmp/protocol_db/data";
67 av[3] = "-F";
68 av[4] = "-k\"/tmp\"";
69 av[5] = NULL;
70
71 system("rm -rf /tmp/protocol_db; mkdir /tmp/protocol_db; cp -r data /tmp/protocol_db");
72 system("cp -r tmp_install /tmp/");
73
74 MemoryContextInit();
75 if(!sigsetjmp(postgre_exit, 0)){
76 postgre_started = true;
77 PostgresMain(5, av, "dbfuzz", "fuzzuser");
78 }
79 pq_endmsgread();
80 return 0;
81 }
82
__wrap_exit(int status)83 void __wrap_exit(int status){
84 if(postgre_started)
85 siglongjmp(postgre_exit, 1);
86 else
87 __real_exit(status);
88 }
89
__wrap_pq_getbyte(void)90 int __wrap_pq_getbyte(void){
91 if(!buffersize) return EOF;
92 unsigned char cur = buffer[0];
93 bufferpointer++; buffersize--;
94 return cur;
95 }
96
97 /*
98 ** Main entry point. The fuzzer invokes this function with each
99 ** fuzzed input.
100 */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)101 int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
102 buffersize = size;
103 buffer = (char *) calloc(size, sizeof(char));
104 bufferpointer = buffer;
105 memcpy(buffer, data, size);
106
107 if(!sigsetjmp(postgre_exit, 0)){
108 postgre_started = true;
109 PostgresMain(5, av, "dbfuzz", "fuzzuser");
110 }
111 pq_endmsgread();
112 postgre_started = false;
113 free(buffer);
114 return 0;
115 }
116