/src/postgres/src/backend/fuzzer/simple_query_fuzzer.c
Line | Count | Source |
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/username.h" |
22 | | #include "executor/spi.h" |
23 | | #include "jit/jit.h" |
24 | | #include "libpq/libpq.h" |
25 | | #include "libpq/pqsignal.h" |
26 | | #include "miscadmin.h" |
27 | | #include "optimizer/optimizer.h" |
28 | | #include "parser/analyze.h" |
29 | | #include "parser/parser.h" |
30 | | #include "storage/proc.h" |
31 | | #include "tcop/tcopprot.h" |
32 | | #include "utils/datetime.h" |
33 | | #include "utils/memutils.h" |
34 | | #include "utils/portal.h" |
35 | | #include "utils/snapmgr.h" |
36 | | #include "utils/timeout.h" |
37 | | |
38 | 4.77k | static void exec_simple_query(const char *query_string) { |
39 | 4.77k | MemoryContext oldcontext; |
40 | 4.77k | List *parsetree_list; |
41 | 4.77k | ListCell *parsetree_item; |
42 | | |
43 | 4.77k | oldcontext = MemoryContextSwitchTo(MessageContext); |
44 | 4.77k | parsetree_list = raw_parser(query_string, RAW_PARSE_TYPE_NAME); |
45 | 4.77k | MemoryContextSwitchTo(oldcontext); |
46 | | |
47 | 4.77k | foreach (parsetree_item, parsetree_list) { |
48 | 371 | RawStmt *parsetree = lfirst_node(RawStmt, parsetree_item); |
49 | 371 | MemoryContext per_parsetree_context = NULL; |
50 | 371 | List *querytree_list; |
51 | | |
52 | 371 | if (lnext(parsetree_list, parsetree_item) != NULL) { |
53 | 0 | per_parsetree_context = |
54 | 0 | AllocSetContextCreate(MessageContext, "per-parsetree message context", ALLOCSET_DEFAULT_SIZES); |
55 | 0 | oldcontext = MemoryContextSwitchTo(per_parsetree_context); |
56 | 371 | } else { |
57 | 371 | oldcontext = MemoryContextSwitchTo(MessageContext); |
58 | 371 | } |
59 | | |
60 | 371 | querytree_list = pg_analyze_and_rewrite_fixedparams(parsetree, query_string, NULL, 0, NULL); |
61 | 371 | pg_plan_queries(querytree_list, query_string, CURSOR_OPT_PARALLEL_OK, NULL); |
62 | | |
63 | 371 | if (per_parsetree_context) { |
64 | 0 | MemoryContextDelete(per_parsetree_context); |
65 | 371 | } else { |
66 | 371 | MemoryContextSwitchTo(oldcontext); |
67 | 371 | } |
68 | 371 | } |
69 | 4.77k | } |
70 | | |
71 | 2 | int LLVMFuzzerInitialize(int *argc, char ***argv) { |
72 | 2 | MemoryContextInit(); |
73 | 2 | InitializeGUCOptions(); |
74 | 2 | InitializeMaxBackends(); |
75 | | |
76 | 2 | MessageContext = AllocSetContextCreate(TopMemoryContext, |
77 | 2 | "MessageContext", |
78 | 2 | ALLOCSET_DEFAULT_SIZES); |
79 | 2 | return 0; |
80 | 2 | } |
81 | | |
82 | 5.14k | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
83 | 5.14k | if (size == 0) |
84 | 0 | return 0; |
85 | | |
86 | 5.14k | sigjmp_buf local_sigjmp_buf; |
87 | 5.14k | char *query_string = (char *) calloc(size + 1, sizeof(char)); |
88 | 5.14k | memcpy(query_string, data, size); |
89 | | |
90 | 5.14k | if (!sigsetjmp(local_sigjmp_buf, 0)) { |
91 | 5.14k | PG_exception_stack = &local_sigjmp_buf; |
92 | 5.14k | error_context_stack = NULL; |
93 | 5.14k | set_stack_base(); |
94 | | |
95 | 5.14k | disable_all_timeouts(false); |
96 | 5.14k | QueryCancelPending = false; |
97 | 5.14k | pq_comm_reset(); |
98 | 5.14k | EmitErrorReport(); |
99 | 5.14k | jit_reset_after_error(); |
100 | | |
101 | 5.14k | MemoryContextSwitchTo(TopMemoryContext); |
102 | 5.14k | FlushErrorState(); |
103 | 5.14k | MemoryContextSwitchTo(MessageContext); |
104 | 5.14k | MemoryContextReset(MessageContext); |
105 | 5.14k | SetCurrentStatementStartTimestamp(); |
106 | | |
107 | 5.14k | exec_simple_query(query_string); |
108 | 5.14k | } |
109 | | |
110 | 5.14k | free(query_string); |
111 | 5.14k | return 0; |
112 | 5.14k | } |