You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
147 lines
3.8 KiB
147 lines
3.8 KiB
// 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/username.h"
|
|
#include "executor/spi.h"
|
|
#include "jit/jit.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/portal.h"
|
|
#include "utils/snapmgr.h"
|
|
#include "utils/timeout.h"
|
|
|
|
static void
|
|
exec_simple_query(const char *query_string)
|
|
{
|
|
MemoryContext oldcontext;
|
|
List *parsetree_list;
|
|
ListCell *parsetree_item;
|
|
bool use_implicit_block;
|
|
|
|
StartTransactionCommand();
|
|
oldcontext = MemoryContextSwitchTo(MessageContext);
|
|
|
|
parsetree_list = raw_parser(query_string, RAW_PARSE_TYPE_NAME);
|
|
MemoryContextSwitchTo(oldcontext);
|
|
|
|
use_implicit_block = (list_length(parsetree_list) > 1);
|
|
|
|
foreach(parsetree_item, parsetree_list)
|
|
{
|
|
RawStmt *parsetree = lfirst_node(RawStmt, parsetree_item);
|
|
bool snapshot_set = false;
|
|
MemoryContext per_parsetree_context = NULL;
|
|
List *querytree_list,
|
|
*plantree_list;
|
|
|
|
if (use_implicit_block)
|
|
BeginImplicitTransactionBlock();
|
|
|
|
if (analyze_requires_snapshot(parsetree))
|
|
{
|
|
PushActiveSnapshot(GetTransactionSnapshot());
|
|
snapshot_set = true;
|
|
}
|
|
|
|
if (lnext(parsetree_list, parsetree_item) != NULL)
|
|
{
|
|
per_parsetree_context =
|
|
AllocSetContextCreate(MessageContext,
|
|
"per-parsetree message context",
|
|
ALLOCSET_DEFAULT_SIZES);
|
|
oldcontext = MemoryContextSwitchTo(per_parsetree_context);
|
|
}
|
|
else
|
|
oldcontext = MemoryContextSwitchTo(MessageContext);
|
|
|
|
querytree_list = pg_analyze_and_rewrite(parsetree, query_string,
|
|
NULL, 0, NULL);
|
|
|
|
plantree_list = pg_plan_queries(querytree_list, query_string,
|
|
CURSOR_OPT_PARALLEL_OK, NULL);
|
|
|
|
if (per_parsetree_context){
|
|
MemoryContextDelete(per_parsetree_context);
|
|
}
|
|
CommitTransactionCommand();
|
|
}
|
|
}
|
|
|
|
|
|
int LLVMFuzzerInitialize(int *argc, char ***argv) {
|
|
FuzzerInitialize("query_db", argv);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
** Main entry point. The fuzzer invokes this function with each
|
|
** fuzzed input.
|
|
*/
|
|
int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
|
char* query_string;
|
|
sigjmp_buf local_sigjmp_buf;
|
|
|
|
query_string = (char*) calloc( (size+1), sizeof(char) );
|
|
memcpy(query_string, data, size);
|
|
|
|
if (!sigsetjmp(local_sigjmp_buf, 0))
|
|
{
|
|
PG_exception_stack = &local_sigjmp_buf;
|
|
error_context_stack = NULL;
|
|
set_stack_base();
|
|
|
|
disable_all_timeouts(false);
|
|
QueryCancelPending = false;
|
|
pq_comm_reset();
|
|
EmitErrorReport();
|
|
|
|
AbortCurrentTransaction();
|
|
|
|
PortalErrorCleanup();
|
|
SPICleanup();
|
|
|
|
jit_reset_after_error();
|
|
|
|
MemoryContextSwitchTo(TopMemoryContext);
|
|
FlushErrorState();
|
|
|
|
MemoryContextSwitchTo(MessageContext);
|
|
MemoryContextResetAndDeleteChildren(MessageContext);
|
|
|
|
InvalidateCatalogSnapshotConditionally();
|
|
|
|
SetCurrentStatementStartTimestamp();
|
|
|
|
exec_simple_query(query_string);
|
|
}
|
|
|
|
free(query_string);
|
|
return 0;
|
|
}
|