# Copyright (c) 2013 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import("//build/config/dcheck_always_on.gni") import("//testing/libfuzzer/fuzzer_test.gni") # Compile-time options passed to SQLite. # # These options are used when building our own SQLite library, which happens # everywhere except on iOS. These compile-time options are exported via a # public_config to all targets using SQLite, because they're needed by the # sqlite.h header. To avoid name clashes (macro names are resolved using a # global namespace), this block should only contain preprocessor macros that # are unambiguously connected to SQLite. # # The vast majority of the macros here are documented at # https://www.sqlite.org/compile.html config("chromium_sqlite3_compile_options") { defines = [ "SQLITE_ENABLE_FTS3", # New unicode61 tokenizer with built-in tables. "SQLITE_DISABLE_FTS3_UNICODE", # Chrome does not enable fts4, disable extra code. "SQLITE_DISABLE_FTS4_DEFERRED", "SQLITE_ENABLE_ICU", # Enables memory tracking needed to release unused memory. # # Needed for sqlite3_release_memory() and its variants to work. Without this # option, the interfaces exist, but the methods are no-ops. "SQLITE_ENABLE_MEMORY_MANAGEMENT", # Defaults the secure_delete pragma to 1. # # This causes SQLite to overwrite all deleted information with zeroes, # trading additional I/O for better privacy guarantees. "SQLITE_SECURE_DELETE", # Custom flag to tweak pcache pools. # TODO(pwnall): This shouldn't use faux-SQLite naming. "SQLITE_SEPARATE_CACHE_POOLS", # TODO(pwnall): SQLite adds mutexes to protect structures which cross # threads. In theory Chrome should be able to turn this to "2" which # should give a slight speed boost. "2" is safe as long as a single # connection is not used by more than one thread at a time. "SQLITE_THREADSAFE=1", # SQLite can spawn threads to sort in parallel if configured # appropriately. Chrome doesn't configure SQLite for that, and would # prefer to control distribution to worker threads. "SQLITE_MAX_WORKER_THREADS=0", # Allow 256MB mmap footprint per connection. Should not be too open-ended # as that could cause memory fragmentation. 50MB encompasses the 99th # percentile of Chrome databases in the wild. # TODO(pwnall): A 64-bit-specific value could be 1G or more. # TODO(pwnall): Figure out if exceeding this is costly. "SQLITE_MAX_MMAP_SIZE=268435456", # Use a read-only memory map when mmap'ed I/O is enabled to prevent memory # stompers from directly corrupting the database. # TODO(pwnall): Upstream the ability to use this define. "SQLITE_MMAP_READ_ONLY=1", # The default POSIX permissions for a newly created SQLite database. # # If unspecified, this defaults to 0644. All the data stored by Chrome is # private, so our databases use stricter settings. "SQLITE_DEFAULT_FILE_PERMISSIONS=0600", # SQLite uses a lookaside buffer to improve performance of small mallocs. # Chrome already depends on small mallocs being efficient, so we disable # this to avoid the extra memory overhead. "SQLITE_DEFAULT_LOOKASIDE=0,0", # Needed by the SQL MemoryDumpProvider. # # Setting this to 1 is needed to collect the information reported by # sqlite3_status64(SQLITE_STATUS_MEMORY_USED). Without this setting, the API # still exists, but does not work as promised. "SQLITE_DEFAULT_MEMSTATUS=1", # Must match sql::Database::kDefaultPageSize. "SQLITE_DEFAULT_PAGE_SIZE=4096", # By default SQLite pre-allocates 100 pages of pcache data, which will not # be released until the handle is closed. This is contrary to Chrome's # memory-usage goals. "SQLITE_DEFAULT_PCACHE_INITSZ=0", # Some defines can affect the amalgamation. Those should be added to # google_generate_amalgamation.sh, and the amalgamation re-generated. # Usually this involves disabling features which include keywords or # syntax, for instance SQLITE_OMIT_VIRTUALTABLE omits the virtual table # syntax entirely. Missing an item usually results in syntax working but # execution failing. Review: # src/src/parse.py # src/tool/mkkeywordhash.c # The flags below are recommended in the SQLite documentation, and disable # features Chrome doesn't use. "SQLITE_LIKE_DOESNT_MATCH_BLOBS", "SQLITE_OMIT_DEPRECATED", "SQLITE_OMIT_PROGRESS_CALLBACK", "SQLITE_OMIT_SHARED_CACHE", "SQLITE_USE_ALLOCA", # Chrome initializes SQLite manually in //sql/connection.cc. "SQLITE_OMIT_AUTOINIT", # Chrome calls sqlite3_reset() correctly to reset prepared statements. "SQLITE_OMIT_AUTORESET", # Chromium does not use sqlite3_{get,free}_table(). # Chrome doesn't use sqlite3_compileoption_{used,get}(). "SQLITE_OMIT_COMPILEOPTION_DIAGS", # Chrome doesn't ship the SQLite shell, so command auto-completion is not # needed. Chrome developers who build the SQLite shell living at # //third_party/sqlite:sqlite_shell for diagnostic purposes will have to # live without auto-completion. "SQLITE_OMIT_COMPLETE", # Chrome does not use sqlite3_column_decltype(). "SQLITE_OMIT_DECLTYPE", # Chrome does not use sqlite3_{get,free}_table(). "SQLITE_OMIT_GET_TABLE", # Chrome does not use sqlite3_{enable_}load_extension(). # Asides from giving us fairly minor code savings, this option disables code # that breaks our method for renaming SQLite's exported symbols. Last, # there's a tiny security benefit to knowing that WebSQL can't possibly # reach extension loading code. "SQLITE_OMIT_LOAD_EXTENSION", # Chrome doesn't use TCL variables. "SQLITE_OMIT_TCL_VARIABLE", # Chrome doesn't use sqlite3_{profile,trace}(). "SQLITE_OMIT_TRACE", # Uses isnan() in the C99 standard library. "SQLITE_HAVE_ISNAN", ] # On OSX, SQLite has extra logic for detecting the use of network # filesystems (e.g., AFS, NFS) and for working around locking problems in # these filesystems. This logic is gated by SQLITE_ENABLE_LOCKING_STYLE, which # is 1 by default on OSX and iOS, and 0 everywhere else. # # When enabled, SQLITE_ENABLE_LOCKING_STYLE results in a compile-time warning # on iOS. The recommended solution is to disable the flag on iOS, because # iOS doesn't (yet?) have networked filesystems. Since we have to do this, # might as well be explicit about the flag everywhere. if (is_mac) { defines += [ "SQLITE_ENABLE_LOCKING_STYLE=1" ] } else { defines += [ "SQLITE_ENABLE_LOCKING_STYLE=0" ] } if (using_sanitizer) { # Limit max length of data blobs and queries to 128 MB for fuzzing builds. defines += [ "SQLITE_MAX_LENGTH=128000000", "SQLITE_MAX_SQL_LENGTH=128000000", "SQLITE_PRINTF_PRECISION_LIMIT=1280000", ] # During fuzz testing, valid SQL queries generated by fuzzing engine may # lead to large memory allocations. If that happens, fuzzer reports an # out-of-memory error. However, such errors are not valid bugs. # To avoid hitting those irrelevant OOMs, we limit max number of memory # pages, so fuzzer will not crash when reaching the limit. # Apply this for fuzzing builds only, not for all builds with sanitizers. if (use_fuzzing_engine) { defines += [ "SQLITE_MAX_PAGE_COUNT=16384" ] } } if (is_debug || dcheck_always_on) { # Check preconditions when SQLite APIs are called. See # https://sqlite.org/compile.html#enable_api_armor defines += [ "SQLITE_ENABLE_API_ARMOR" ] } } config("sqlite_warnings") { cflags = [] if (is_clang) { # sqlite contains a few functions that are unused, at least on # Windows with Chrome's sqlite patches applied # (interiorCursorEOF fts3EvalDeferredPhrase # fts3EvalSelectDeferred sqlite3Fts3InitHashTable # sqlite3Fts3InitTok). cflags += [ "-Wno-unused-function" ] } if (is_linux) { cflags += [ # SQLite doesn"t believe in compiler warnings, # preferring testing. # http://www.sqlite.org/faq.html#q17 "-Wno-int-to-pointer-cast", "-Wno-pointer-to-int-cast", ] } if (is_ios) { cflags += [ # SQLite issues a #pragma warning on iOS. # http://sqlite.1065341.n5.nabble.com/Compiler-warning-quot-gethostuuid-is-disabled-quot-building-SQLite-for-iOS-td96881.html # # Contrary to what is said on the mailing list, setting # SQLITE_ENABLE_LOCKING_STYLE to 0 does not make the warning go away. "-Wno-#warnings", ] } if (is_win && !is_clang) { cflags += [ "/wd4101" ] # 'zTrace' unreferenced variable in src/vdbe.c } } # Naming the library "sqlite3" can cause conflicts with the system library. component("chromium_sqlite3") { visibility = [ ":*" ] public = [ "sqlite3.h", "src/src/recover.h", ] sources = [ "amalgamation/sqlite3.h", "sqlite3_shim.c", "src/src/recover.c", "src/src/recover_varint.c", ] inputs = [ # This file is #included into sqlite3_shim.c, which injects Chrome-specific # definitions into the SQLite amalgamation code. "amalgamation/sqlite3.c", ] cflags = [] defines = [] if (is_component_build) { if (is_win) { defines += [ "SQLITE_API=__declspec(dllexport)" ] } else { defines += [ "SQLITE_API=__attribute__((visibility(\"default\")))" ] } } if (is_linux || is_android) { defines += [ # Linux provides fdatasync(), a faster equivalent of fsync(). "fdatasync=fdatasync", ] } if (is_posix || is_fuchsia) { defines += [ # Allow xSleep() call on Unix to use usleep() rather than sleep(), so it # will have microsecond precision. Should only affect contended # databases via the busy callback. Browser profile databases are mostly # exclusive, but renderer databases may allow for contention. "HAVE_USLEEP=1", # Use pread/pwrite directly rather than emulating them. "USE_PREAD=1", ] } include_dirs = [ ".", # sqlite3.h here must override the one in amalgamation/. "amalgamation", ] configs -= [ "//build/config/compiler:chromium_code" ] configs += [ ":chromium_sqlite3_compile_options", "//build/config/compiler:no_chromium_code", "//build/config/sanitizers:cfi_icall_generalize_pointers", # Must be after no_chromium_code for warning flags to be ordered correctly. ":sqlite_warnings", ] if (is_mac || is_ios) { libs = [ "CoreFoundation.framework" ] if (!is_ios) { libs += [ "CoreServices.framework" ] } } else if (is_android) { defines += [ "SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT=1048576", "SQLITE_DEFAULT_AUTOVACUUM=1", "SQLITE_TEMP_STORE=3", ] } deps = [ "//third_party/icu", ] } config("sqlite_export") { if (is_component_build && is_win) { defines = [ "SQLITE_API=__declspec(dllimport)" ] } } # This is used to allow the SQLITE_API definition to be different when # building sqlite3.c than it is when clients include sqlite3.h. group("sqlite") { public_deps = [ ":chromium_sqlite3", ] public_configs = [ ":chromium_sqlite3_compile_options", ":sqlite_export", ] } if (is_linux) { executable("sqlite_shell") { include_dirs = [ # shell.c contains an '#include "sqlite3.h", which we want to be # resolved to //third_party/sqlite/shell.h. ".", ] sources = [ "amalgamation/shell/shell.c", "src/src/shell_icu_linux.c", # Include a dummy c++ file to force linking of libstdc++. "build_as_cpp.cc", ] deps = [ ":sqlite", "//third_party/icu", ] configs -= [ "//build/config/compiler:chromium_code" ] configs += [ ":chromium_sqlite3_compile_options", "//build/config/compiler:no_chromium_code", # Must be after no_chromium_code for warning flags to be ordered # correctly. ":sqlite_warnings", ] } } fuzzer_test("sqlite3_prepare_v2_fuzzer") { sources = [ "fuzz/sqlite3_prepare_v2_fuzzer.cc", ] deps = [ ":sqlite", ] dict = "fuzz/sqlite3_prepare_v2_fuzzer.dict" } fuzzer_test("sqlite3_ossfuzz_fuzzer") { # TODO(mmoroz, pwnall): remove fuzz/ossfuzz.c in favor of test/osfuzz.c in # sqlite's source code sources = [ "fuzz/ossfuzz.c", ] deps = [ ":sqlite", ] dict = "fuzz/sql.dict" }