• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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