Skip to content

Commit 8bbc2dc

Browse files
committed
postgresql: Fix fuzzer
Signed-off-by: Arthur Chan <arthur.chan@adalogics.com>
1 parent bf3295e commit 8bbc2dc

File tree

5 files changed

+73
-147
lines changed

5 files changed

+73
-147
lines changed

projects/expat/Dockerfile

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
# Copyright 2016 Google Inc.
2-
# Copyright 2025 Sebastian Pipping <sebastian@pipping.org>
1+
# Copyright 2025 Google LLC.
32
#
43
# Licensed under the Apache License, Version 2.0 (the "License");
54
# you may not use this file except in compliance with the License.
@@ -14,7 +13,6 @@
1413
# limitations under the License.
1514
#
1615
################################################################################
17-
1816
FROM gcr.io/oss-fuzz-base/base-builder
1917
RUN apt-get update && apt-get install -y \
2018
cmake \
@@ -23,7 +21,7 @@ RUN apt-get update && apt-get install -y \
2321
libstdc++-9-dev:i386 \
2422
make \
2523
protobuf-compiler
26-
27-
RUN git clone --depth 1 https://github.com/libexpat/libexpat expat
28-
WORKDIR expat
29-
COPY build.sh *.dict $SRC/
24+
COPY *.sh *.dict *.diff $SRC/
25+
RUN git clone https://android.googlesource.com/platform/external/expat expat
26+
WORKDIR $SRC/expat
27+
COPY *.c $SRC/expat/expat/fuzz/

projects/expat/build.sh

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#!/bin/bash -eu
2-
# Copyright 2016 Google Inc.
3-
# Copyright 2025 Sebastian Pipping <sebastian@pipping.org>
2+
# Copyright 2025 Google LLC.
43
#
54
# Licensed under the Apache License, Version 2.0 (the "License");
65
# you may not use this file except in compliance with the License.
@@ -15,54 +14,38 @@
1514
# limitations under the License.
1615
#
1716
################################################################################
17+
git apply $SRC/fuzzer.diff
1818

19-
# NOTE: We need to drop -stdlib=libc++ to not get (pages of) link errors when
20-
# linking against system Protobuf that is linked against GCC's libstdc++
21-
# rather than Clang's own libstdc++
2219
CXXFLAGS="${CXXFLAGS/-stdlib=libc++/ }"
23-
24-
# NOTE: Without -static-libstdc++, the bad build checker in base-runner
25-
# will fail with output:
26-
# > error while loading shared libraries: libstdc++.so.6:
27-
# > cannot open shared object file: No such file or directory
28-
# The addition of -Wno-unused-command-line-argument silences Clang's
29-
# misleading output on argument -static-libstdc++ appearing as unused.
3020
CXXFLAGS="${CXXFLAGS} -static-libstdc++ -Wno-unused-command-line-argument"
3121

32-
: ${LD:="${CXX}"}
33-
: ${LDFLAGS:="${CXXFLAGS}"} # to make sure we link with sanitizer runtime
34-
3522
cmake_args=(
36-
# Specific to Expat
3723
-DEXPAT_BUILD_DOCS=OFF
3824
-DEXPAT_BUILD_EXAMPLES=OFF
3925
-DEXPAT_BUILD_FUZZERS=ON
4026
-DEXPAT_BUILD_TESTS=OFF
4127
-DEXPAT_BUILD_TOOLS=OFF
4228
-DEXPAT_OSSFUZZ_BUILD=ON
4329
-DEXPAT_SHARED_LIBS=OFF
44-
-DProtobuf_USE_STATIC_LIBS=ON
4530

46-
# C compiler
4731
-DCMAKE_C_COMPILER="${CC}"
4832
-DCMAKE_C_FLAGS="${CFLAGS}"
49-
50-
# C++ compiler
5133
-DCMAKE_CXX_COMPILER="${CXX}"
5234
-DCMAKE_CXX_FLAGS="${CXXFLAGS}"
5335

54-
# Linker
55-
-DCMAKE_LINKER="${LD}"
56-
-DCMAKE_EXE_LINKER_FLAGS="${LDFLAGS}"
57-
-DCMAKE_MODULE_LINKER_FLAGS="${LDFLAGS}"
58-
-DCMAKE_SHARED_LINKER_FLAGS="${LDFLAGS}"
36+
-DCMAKE_LINKER="ld.lld"
37+
-DCMAKE_EXE_LINKER_FLAGS="${CXXFLAGS}"
38+
-DCMAKE_MODULE_LINKER_FLAGS="${CXXFLAGS}"
39+
-DCMAKE_SHARED_LINKER_FLAGS="${CXXFLAGS}"
5940
)
6041

6142
mkdir -p build
6243
cd build
6344
cmake ../expat "${cmake_args[@]}"
6445
make -j$(nproc)
6546

47+
libexpat_path=$(find . -name 'libexpat.a' | head -n 1)
48+
6649
for fuzzer in fuzz/*;
6750
do
6851
cp $fuzzer $OUT

projects/expat/project.yaml

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,6 @@
1-
homepage: "https://github.com/libexpat/libexpat"
2-
language: c++
3-
primary_contact: "sebastian@pipping.org"
1+
homepage: "https://github.com/google/oss-fuzz"
2+
language: c
3+
primary_contact: "info@oss-fuzz.com"
44
auto_ccs:
5-
- "rhodri@kynesim.co.uk"
6-
- "hanno@hboeck.de"
7-
- "webmaster@hartwork.org"
8-
- "bshas3@gmail.com"
9-
vendor_ccs:
10-
- "twsmith@mozilla.com"
11-
sanitizers:
12-
- address
13-
- memory
14-
- undefined
15-
architectures:
16-
- x86_64
17-
- i386
18-
main_repo: 'https://github.com/libexpat/libexpat'
19-
20-
fuzzing_engines:
21-
- afl
22-
- honggfuzz
23-
- libfuzzer
24-
5+
-
6+
main_repo: 'https://github.com/google/oss-fuzz'

projects/postgresql/build.sh

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,6 @@ make -j$(nproc) fuzzer
6767
#if [ "$FUZZING_ENGINE" = "afl" ]
6868
#then
6969
rm protocol_fuzzer
70-
rm simple_query_fuzzer
7170
#fi
7271
cp *_fuzzer $OUT/
7372
cp $SRC/postgresql_fuzzer_seed_corpus.zip $OUT/
74-
75-
# Temporary fix. Todo: David fix this.
76-
#rm $OUT/protocol_fuzzer

projects/postgresql/fuzzer/simple_query_fuzzer.c

Lines changed: 55 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -35,110 +35,77 @@
3535
#include "utils/snapmgr.h"
3636
#include "utils/timeout.h"
3737

38-
static void
39-
exec_simple_query(const char *query_string)
40-
{
38+
static void exec_simple_query(const char *query_string) {
4139
MemoryContext oldcontext;
42-
List *parsetree_list;
43-
ListCell *parsetree_item;
44-
bool use_implicit_block;
40+
List *parsetree_list;
41+
ListCell *parsetree_item;
4542

46-
StartTransactionCommand();
4743
oldcontext = MemoryContextSwitchTo(MessageContext);
48-
4944
parsetree_list = raw_parser(query_string, RAW_PARSE_TYPE_NAME);
5045
MemoryContextSwitchTo(oldcontext);
5146

52-
use_implicit_block = (list_length(parsetree_list) > 1);
53-
54-
foreach(parsetree_item, parsetree_list)
55-
{
56-
RawStmt *parsetree = lfirst_node(RawStmt, parsetree_item);
57-
bool snapshot_set = false;
58-
MemoryContext per_parsetree_context = NULL;
59-
List *querytree_list,
60-
*plantree_list;
61-
62-
if (use_implicit_block)
63-
BeginImplicitTransactionBlock();
64-
65-
if (analyze_requires_snapshot(parsetree))
66-
{
67-
PushActiveSnapshot(GetTransactionSnapshot());
68-
snapshot_set = true;
69-
}
70-
71-
if (lnext(parsetree_list, parsetree_item) != NULL)
72-
{
73-
per_parsetree_context =
74-
AllocSetContextCreate(MessageContext,
75-
"per-parsetree message context",
76-
ALLOCSET_DEFAULT_SIZES);
77-
oldcontext = MemoryContextSwitchTo(per_parsetree_context);
78-
}
79-
else
80-
oldcontext = MemoryContextSwitchTo(MessageContext);
81-
82-
querytree_list = pg_analyze_and_rewrite_fixedparams(parsetree, query_string,
83-
NULL, 0, NULL);
84-
85-
plantree_list = pg_plan_queries(querytree_list, query_string,
86-
CURSOR_OPT_PARALLEL_OK, NULL);
87-
88-
if (per_parsetree_context){
89-
MemoryContextDelete(per_parsetree_context);
90-
}
91-
CommitTransactionCommand();
47+
foreach (parsetree_item, parsetree_list) {
48+
RawStmt *parsetree = lfirst_node(RawStmt, parsetree_item);
49+
MemoryContext per_parsetree_context = NULL;
50+
List *querytree_list;
51+
52+
if (lnext(parsetree_list, parsetree_item) != NULL) {
53+
per_parsetree_context =
54+
AllocSetContextCreate(MessageContext, "per-parsetree message context", ALLOCSET_DEFAULT_SIZES);
55+
oldcontext = MemoryContextSwitchTo(per_parsetree_context);
56+
} else {
57+
oldcontext = MemoryContextSwitchTo(MessageContext);
9258
}
93-
}
9459

60+
querytree_list = pg_analyze_and_rewrite_fixedparams(parsetree, query_string, NULL, 0, NULL);
61+
pg_plan_queries(querytree_list, query_string, CURSOR_OPT_PARALLEL_OK, NULL);
62+
63+
if (per_parsetree_context) {
64+
MemoryContextDelete(per_parsetree_context);
65+
} else {
66+
MemoryContextSwitchTo(oldcontext);
67+
}
68+
}
69+
}
9570

9671
int LLVMFuzzerInitialize(int *argc, char ***argv) {
97-
FuzzerInitialize("query_db", argv);
98-
return 0;
72+
MemoryContextInit();
73+
InitializeGUCOptions();
74+
InitializeMaxBackends();
75+
76+
MessageContext = AllocSetContextCreate(TopMemoryContext,
77+
"MessageContext",
78+
ALLOCSET_DEFAULT_SIZES);
79+
return 0;
9980
}
10081

82+
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
83+
if (size == 0)
84+
return 0;
10185

102-
/*
103-
** Main entry point. The fuzzer invokes this function with each
104-
** fuzzed input.
105-
*/
106-
int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
107-
char* query_string;
10886
sigjmp_buf local_sigjmp_buf;
109-
110-
query_string = (char*) calloc( (size+1), sizeof(char) );
87+
char *query_string = (char *) calloc(size + 1, sizeof(char));
11188
memcpy(query_string, data, size);
11289

113-
if (!sigsetjmp(local_sigjmp_buf, 0))
114-
{
115-
PG_exception_stack = &local_sigjmp_buf;
116-
error_context_stack = NULL;
117-
set_stack_base();
118-
119-
disable_all_timeouts(false);
120-
QueryCancelPending = false;
121-
pq_comm_reset();
122-
EmitErrorReport();
123-
124-
AbortCurrentTransaction();
125-
126-
PortalErrorCleanup();
127-
128-
jit_reset_after_error();
129-
130-
MemoryContextSwitchTo(TopMemoryContext);
131-
FlushErrorState();
132-
133-
MemoryContextSwitchTo(MessageContext);
134-
MemoryContextReset(MessageContext);
135-
136-
InvalidateCatalogSnapshotConditionally();
137-
138-
SetCurrentStatementStartTimestamp();
139-
140-
exec_simple_query(query_string);
141-
}
90+
if (!sigsetjmp(local_sigjmp_buf, 0)) {
91+
PG_exception_stack = &local_sigjmp_buf;
92+
error_context_stack = NULL;
93+
set_stack_base();
94+
95+
disable_all_timeouts(false);
96+
QueryCancelPending = false;
97+
pq_comm_reset();
98+
EmitErrorReport();
99+
jit_reset_after_error();
100+
101+
MemoryContextSwitchTo(TopMemoryContext);
102+
FlushErrorState();
103+
MemoryContextSwitchTo(MessageContext);
104+
MemoryContextReset(MessageContext);
105+
SetCurrentStatementStartTimestamp();
106+
107+
exec_simple_query(query_string);
108+
}
142109

143110
free(query_string);
144111
return 0;

0 commit comments

Comments
 (0)