2  * Copyright (c) 2012-2017 Apple Inc. All Rights Reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. Please obtain a copy of the License at 
  10  * http://www.opensource.apple.com/apsl/ and read it before using this 
  13  * The Original Code and all software distributed under the License are 
  14  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  15  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  16  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  17  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  18  * Please see the License for the specific language governing rights and 
  19  * limitations under the License. 
  21  * @APPLE_LICENSE_HEADER_END@ 
  26 #include "SecDbInternal.h" 
  27 #include "debugging.h" 
  30 #include <sqlite3_private.h> 
  31 #include <CoreFoundation/CoreFoundation.h> 
  35 #include <AssertMacros.h> 
  36 #include "SecCFWrappers.h" 
  37 #include "SecCFError.h" 
  38 #include "SecIOFormat.h" 
  40 #include "Security/SecBase.h" 
  41 #include "SecAutorelease.h" 
  42 #include <os/assumes.h> 
  43 #include <xpc/private.h>    // xpc_transaction_exit_clean() 
  47 // Architecturally inverted files 
  48 // These are in SecureObjectSync but utilities depends on them 
  49 // <rdar://problem/20802079> Fix layer violation (SOSDigestVector, SOSManifest, SecDB.c) 
  51 #include "keychain/SecureObjectSync/SOSDigestVector.h" 
  52 #include "keychain/SecureObjectSync/SOSManifest.h" 
  54 #define SECDB_DEBUGGING 0 
  56 struct __OpaqueSecDbStatement 
{ 
  59     SecDbConnectionRef dbconn
; 
  63 struct __OpaqueSecDbConnection 
{ 
  66     //CFMutableDictionaryRef statements; 
  68     SecDbRef db
;     // NONRETAINED, since db or block retains us 
  71     SecDbTransactionSource source
; 
  73     int maybeCorruptedCode
; 
  75     CFErrorRef corruptionError
; 
  77     // Pending deletions and additions for the current transaction 
  78     // Entires are either: 
  79     // 1) a CFArrayRef of 1 element representing a deletion, 
  80     // 2) a CFArrayRef of 2 elements representing the element 0 having been replaced with element 1 
  81     // 3) a CFTypeRef that is not a CFArrayRef, representing an add of the element in question. 
  82     CFMutableArrayRef changes
; 
  85 struct __OpaqueSecDb 
{ 
  89     dispatch_queue_t queue
; 
  90     dispatch_queue_t commitQueue
; 
  92     CFMutableArrayRef idleWriteConnections
;     // up to kSecDbMaxWriters of them (currently 1, requires locking change for >1) 
  93     CFMutableArrayRef idleReadConnections
;      // up to kSecDbMaxReaders of them 
  94     pthread_mutex_t writeMutex
; 
  95     // TODO: Replace after we have rdar://problem/60961964 
  96     dispatch_semaphore_t readSemaphore
; 
  99     bool (^opened
)(SecDbRef db
, SecDbConnectionRef dbconn
, bool didCreate
, bool *callMeAgainForNextConnection
, CFErrorRef 
*error
); 
 100     bool callOpenedHandlerForNextConnection
; 
 101     CFMutableArrayRef notifyPhase
; /* array of SecDBNotifyBlock */ 
 102     mode_t mode
; /* database file permissions */ 
 103     bool readWrite
; /* open database read-write */ 
 104     bool allowRepair
; /* allow database repair */ 
 105     bool useWAL
; /* use WAL mode */ 
 106     bool useRobotVacuum
; /* use if SecDB should manage vacuum behind your back */ 
 107     uint8_t maxIdleHandles
; 
 108     void (^corruptionReset
)(void); 
 111 // MARK: Error domains and error helper functions 
 113 CFStringRef kSecDbErrorDomain 
= CFSTR("com.apple.utilities.sqlite3"); 
 115 bool SecDbError(int sql_code
, CFErrorRef 
*error
, CFStringRef format
, ...) { 
 116     if (sql_code 
== SQLITE_OK
) return true; 
 120         CFIndex code 
= sql_code
; 
 121         CFErrorRef previousError 
= *error
; 
 124         va_start(args
, format
); 
 125         SecCFCreateErrorWithFormatAndArguments(code
, kSecDbErrorDomain
, previousError
, error
, NULL
, format
, args
); 
 131 bool SecDbErrorWithDb(int sql_code
, sqlite3 
*db
, CFErrorRef 
*error
, CFStringRef format
, ...) { 
 132     if (sql_code 
== SQLITE_OK
) return true; 
 135         va_start(args
, format
); 
 136         CFStringRef message 
= CFStringCreateWithFormatAndArguments(kCFAllocatorDefault
, NULL
, format
, args
); 
 138         CFStringRef errno_code 
= NULL
; 
 140         if (sql_code 
== SQLITE_CANTOPEN
) { 
 141             int errno_number 
= sqlite3_system_errno(db
); 
 142             errno_code 
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%d"), errno_number
); 
 144             errno_code 
= CFRetain(CFSTR("")); 
 147         int extended_code 
= sqlite3_extended_errcode(db
); 
 148         if (sql_code 
== extended_code
) 
 149             SecDbError(sql_code
, error
, CFSTR("%@: [%d]%@ %s"), message
, sql_code
, errno_code
, sqlite3_errmsg(db
)); 
 151             SecDbError(sql_code
, error
, CFSTR("%@: [%d->%d]%@ %s"), message
, sql_code
, extended_code
, errno_code
, sqlite3_errmsg(db
)); 
 152         CFReleaseSafe(message
); 
 153         CFReleaseSafe(errno_code
); 
 158 bool SecDbErrorWithStmt(int sql_code
, sqlite3_stmt 
*stmt
, CFErrorRef 
*error
, CFStringRef format
, ...) { 
 159     if (sql_code 
== SQLITE_OK
) return true; 
 162         va_start(args
, format
); 
 163         CFStringRef message 
= CFStringCreateWithFormatAndArguments(kCFAllocatorDefault
, NULL
, format
, args
); 
 166         sqlite3 
*db 
= sqlite3_db_handle(stmt
); 
 167         const char *sql 
= sqlite3_sql(stmt
); 
 168         int extended_code 
= sqlite3_extended_errcode(db
); 
 169         if (sql_code 
== extended_code
) 
 170             SecDbError(sql_code
, error
, CFSTR("%@: [%d] %s sql: %s"), message
, sql_code
, sqlite3_errmsg(db
), sql
); 
 172             SecDbError(sql_code
, error
, CFSTR("%@: [%d->%d] %s sql: %s"), message
, sql_code
, extended_code
, sqlite3_errmsg(db
), sql
); 
 173         CFReleaseSafe(message
); 
 178 // A callback for the sqlite3_log() interface. 
 179 static void sqlite3Log(void *pArg
, int iErrCode
, const char *zMsg
){ 
 180     secdebug("sqlite3", "(%d) %s", iErrCode
, zMsg
); 
 183 void _SecDbServerSetup(void) 
 185     static dispatch_once_t onceToken
; 
 186     dispatch_once(&onceToken
, ^{ 
 187         int rx 
= sqlite3_config(SQLITE_CONFIG_LOG
, sqlite3Log
, NULL
); 
 188         if (SQLITE_OK 
!= rx
) { 
 189             secwarning("Could not set up sqlite global error logging to syslog: %d", rx
); 
 196 // MARK: Static helper functions 
 198 static bool SecDbOpenHandle(SecDbConnectionRef dbconn
, bool *created
, CFErrorRef 
*error
); 
 199 static bool SecDbHandleCorrupt(SecDbConnectionRef dbconn
, int rc
, CFErrorRef 
*error
); 
 202 #pragma mark SecDbRef 
 205 SecDbCopyFormatDescription(CFTypeRef value
, CFDictionaryRef formatOptions
) 
 207     SecDbRef db 
= (SecDbRef
)value
; 
 208     return CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("<SecDb path:%@ connections: %@>"), db
->db_path
, db
->idleReadConnections
); 
 213 SecDbDestroy(CFTypeRef value
) 
 215     SecDbRef db 
= (SecDbRef
)value
; 
 217     CFReleaseNull(db
->db_path
); 
 218     dispatch_sync(db
->queue
, ^{ 
 219         CFReleaseNull(db
->idleWriteConnections
); 
 220         CFReleaseNull(db
->idleReadConnections
); 
 224         dispatch_release(db
->queue
); 
 227     if (db
->commitQueue
) { 
 228         dispatch_release(db
->commitQueue
); 
 229         db
->commitQueue 
= NULL
; 
 232     pthread_mutex_destroy(&(db
->writeMutex
)); 
 234     if (db
->readSemaphore
) { 
 235         dispatch_release(db
->readSemaphore
); 
 236         db
->readSemaphore 
= NULL
; 
 240         Block_release(db
->opened
); 
 243     CFReleaseNull(db
->notifyPhase
); 
 249 SecDbCreate(CFStringRef dbName
, mode_t mode
, bool readWrite
, bool allowRepair
, bool useWAL
, bool useRobotVacuum
, uint8_t maxIdleHandles
, 
 250                        bool (^opened
)(SecDbRef db
, SecDbConnectionRef dbconn
, bool didCreate
, bool *callMeAgainForNextConnection
, CFErrorRef 
*error
)) 
 254     db 
= CFTypeAllocate(SecDb
, struct __OpaqueSecDb
, kCFAllocatorDefault
); 
 255     require(db 
!= NULL
, done
); 
 257     CFStringPerformWithCString(dbName
, ^(const char *dbNameStr
) { 
 258         db
->queue 
= dispatch_queue_create(dbNameStr
, DISPATCH_QUEUE_SERIAL
); 
 260     CFStringRef commitQueueStr 
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("%@-commit"), dbName
); 
 261     CFStringPerformWithCString(commitQueueStr
, ^(const char *cqNameStr
) { 
 262         db
->commitQueue 
= dispatch_queue_create(cqNameStr
, DISPATCH_QUEUE_CONCURRENT
); 
 264     CFReleaseNull(commitQueueStr
); 
 265     db
->readSemaphore 
= dispatch_semaphore_create(kSecDbMaxReaders
); 
 266     if (pthread_mutex_init(&(db
->writeMutex
), NULL
) != 0) { 
 267         seccritical("SecDb: SecDbCreate failed to init the write mutex, this will end badly"); 
 269     db
->idleWriteConnections 
= CFArrayCreateMutableForCFTypes(kCFAllocatorDefault
); 
 270     db
->idleReadConnections 
= CFArrayCreateMutableForCFTypes(kCFAllocatorDefault
); 
 271     db
->opened 
= opened 
? Block_copy(opened
) : NULL
; 
 272     if (getenv("__OSINSTALL_ENVIRONMENT") != NULL
) { 
 273         // TODO: Move this code out of this layer 
 274         secinfo("#SecDB", "SecDB: running from installer"); 
 276         db
->db_path 
= CFSTR("file::memory:?cache=shared"); 
 278         db
->db_path 
= CFStringCreateCopy(kCFAllocatorDefault
, dbName
); 
 281     db
->readWrite 
= readWrite
; 
 282     db
->allowRepair 
= allowRepair
; 
 284     db
->useRobotVacuum 
= useRobotVacuum
; 
 285     db
->maxIdleHandles 
= maxIdleHandles
; 
 286     db
->corruptionReset 
= NULL
; 
 293 SecDbIdleConnectionCount(SecDbRef db
) { 
 294     __block CFIndex count 
= 0; 
 295     dispatch_sync(db
->queue
, ^{ 
 296         count 
= CFArrayGetCount(db
->idleReadConnections
); 
 297         count 
+= CFArrayGetCount(db
->idleWriteConnections
); 
 302 void SecDbAddNotifyPhaseBlock(SecDbRef db
, SecDBNotifyBlock notifyPhase
) 
 304 #if !TARGET_OS_BRIDGE 
 305     // SecDbNotifyPhase seems to mostly be called on the db's commitQueue, and not the db's queue. Therefore, protect the array with that queue. 
 306     dispatch_sync(db
->commitQueue
, ^{ 
 307         SecDBNotifyBlock block 
= Block_copy(notifyPhase
); /* Force the block off the stack */ 
 308         if (db
->notifyPhase 
== NULL
) { 
 309             db
->notifyPhase 
= CFArrayCreateMutableForCFTypes(NULL
); 
 311         CFArrayAppendValue(db
->notifyPhase
, block
); 
 312         Block_release(block
); 
 317 static void SecDbNotifyPhase(SecDbConnectionRef dbconn
, SecDbTransactionPhase phase
) { 
 318 #if !TARGET_OS_BRIDGE 
 319     if (CFArrayGetCount(dbconn
->changes
)) { 
 320         CFArrayRef changes 
= dbconn
->changes
; 
 321         dbconn
->changes 
= CFArrayCreateMutableForCFTypes(kCFAllocatorDefault
); 
 322         if (dbconn
->db
->notifyPhase
) { 
 323             CFArrayForEach(dbconn
->db
->notifyPhase
, ^(const void *value
) { 
 324                 SecDBNotifyBlock notifyBlock 
= (SecDBNotifyBlock
)value
; 
 325                 notifyBlock(dbconn
, phase
, dbconn
->source
, changes
); 
 328         CFReleaseSafe(changes
); 
 333 static void SecDbOnNotify(SecDbConnectionRef dbconn
, void (^perform
)(void)) { 
 337 CFStringRef 
SecDbGetPath(SecDbRef db
) { 
 346 #pragma mark SecDbConnectionRef 
 348 static bool SecDbCheckCorrupted(SecDbConnectionRef dbconn
) 
 350     __block 
bool checkDidRun 
= false; 
 351     __block 
bool isCorrupted 
= false; 
 352     __block CFErrorRef error 
= NULL
; 
 353     SecDbPrepare(dbconn
, CFSTR("PRAGMA integrity_check"), &error
, ^(sqlite3_stmt 
*stmt
) { 
 354         SecDbStep(dbconn
, stmt
, &error
, ^(bool *stop
) { 
 355             const char * result 
= (const char*)sqlite3_column_text(stmt
, 0); 
 356             if (!result 
|| strncasecmp(result
, "ok", 3) != 0) { 
 358                 secerror("SecDBCheckCorrupted integrity_check returned %s", (result
) ? result 
: "NULL"); 
 364         // An error occurred in SecDbPrepare before we could run the block. 
 366             CFIndex code 
= CFErrorGetCode(error
); 
 367             if (SQLITE_CORRUPT 
== code 
|| SQLITE_NOTADB 
== code
) { 
 370             secinfo("#SecDB", "#SecDB warning error %{public}@ when running integrity check", error
); 
 372             // We don't have an error ref if SecDbPrepare has called SecDbConnectionCheckCode, 
 373             // which then called SecDbHandleCorrupt. That code path is only entered when the 
 374             // original error was SQLITE_CORRUPT or SQLITE_NOTADB. On other errors, the 
 375             // CFErrorRef is not cleared and we can just check the code above. 
 377             secinfo("#SecDB", "#SecDB warning: failed to run integrity check due to corruption"); 
 382             secerror("SecDBCheckCorrupted ran integrity_check, and that didn't return ok"); 
 384             secerror("SecDBCheckCorrupted failed to run integrity check"); 
 387     CFReleaseNull(error
); 
 392 static bool SecDbDidCreateFirstConnection(SecDbConnectionRef dbconn
, bool didCreate
, CFErrorRef 
*error
) 
 394     secinfo("#SecDB", "#SecDB starting maintenance"); 
 397     // Historical note: this used to check for integrity but that became too slow and caused panics at boot. 
 398     // Now, just react to SQLite errors when doing an operation. If file on disk is borked it'll tell us right away. 
 400     if (!dbconn
->isCorrupted 
&& dbconn
->db
->opened
) { 
 401         CFErrorRef localError 
= NULL
; 
 403         dbconn
->db
->callOpenedHandlerForNextConnection 
= false; 
 404         ok 
= dbconn
->db
->opened(dbconn
->db
, dbconn
, didCreate
, &dbconn
->db
->callOpenedHandlerForNextConnection
, &localError
); 
 407             secerror("opened block failed: %@", localError
); 
 409         if (!dbconn
->isCorrupted 
&& error 
&& *error 
== NULL
) { 
 414                 secerror("opened block failed: error (%@) is being released and lost", localError
); 
 415             CFReleaseNull(localError
); 
 419     if (dbconn
->isCorrupted
) { 
 420         ok 
= SecDbHandleCorrupt(dbconn
, 0, error
); 
 423     secinfo("#SecDB", "#SecDB starting maintenance"); 
 427 void SecDbCorrupt(SecDbConnectionRef dbconn
, CFErrorRef error
) 
 429     if (__security_simulatecrash_enabled()) { 
 430         os_log_fault(secLogObjForScope("SecEmergency"), "SecDBCorrupt: %@", error
); 
 432     dbconn
->isCorrupted 
= true; 
 433     CFRetainAssign(dbconn
->corruptionError
, error
); 
 437 static uint8_t knownDbPathIndex(SecDbConnectionRef dbconn
) 
 440     if(CFEqual(dbconn
->db
->db_path
, CFSTR("/Library/Keychains/keychain-2.db"))) 
 442     if(CFEqual(dbconn
->db
->db_path
, CFSTR("/Library/Keychains/ocspcache.sqlite3"))) 
 444     if(CFEqual(dbconn
->db
->db_path
, CFSTR("/Library/Keychains/TrustStore.sqlite3"))) 
 446     if(CFEqual(dbconn
->db
->db_path
, CFSTR("/Library/Keychains/caissuercache.sqlite3"))) 
 449     /* Unknown DB path */ 
 453 static bool SecDbConnectionCheckCode(SecDbConnectionRef dbconn
, int code
, CFErrorRef 
*error
, CFStringRef desc
, ...) 
 454     CF_FORMAT_FUNCTION(4, 5); 
 456 // Return true if there was no error, returns false otherwise and set *error to an appropriate CFErrorRef. 
 457 static bool SecDbConnectionCheckCode(SecDbConnectionRef dbconn
, int code
, CFErrorRef 
*error
, CFStringRef desc
, ...) { 
 458     if (code 
== SQLITE_OK 
|| code 
== SQLITE_DONE
) 
 463         va_start(args
, desc
); 
 464         CFStringRef msg 
= CFStringCreateWithFormatAndArguments(kCFAllocatorDefault
, NULL
, desc
, args
); 
 466         SecDbErrorWithDb(code
, dbconn
->handle
, error
, CFSTR("%@"), msg
); 
 470     dbconn
->hasIOFailure 
|= (SQLITE_IOERR 
== code
); 
 472     /* If it's already corrupted, don't try to recover */ 
 473     if (dbconn
->isCorrupted
) { 
 474         CFStringRef reason 
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, 
 475                                                       CFSTR("SQL DB %@ is corrupted already. Corruption error was: %d (previously %d)"), 
 476                                                       dbconn
->db
->db_path
, code
, dbconn
->maybeCorruptedCode
); 
 477         secerror("%@",reason
); 
 478         __security_simulatecrash(reason
, __sec_exception_code_TwiceCorruptDb(knownDbPathIndex(dbconn
))); 
 479         CFReleaseSafe(reason
); 
 480         // We can't fall through to the checking case because it eventually calls SecDbConnectionCheckCode again. 
 481         // However, this is the second time we're seeing corruption so let's take the ultimate measure. 
 482         if ((SQLITE_CORRUPT 
== code
) || (SQLITE_NOTADB 
== code
)) { 
 483             secerror("SecDbConnectionCheckCode detected corruption twice: going to handle corrupt DB"); 
 484             (void)SecDbHandleCorrupt(dbconn
, code
, error
); 
 489     // NOTADB means file is garbage, so it's functionally equivalent to corruption 
 490     dbconn
->isCorrupted 
= (SQLITE_CORRUPT 
== code
) || (SQLITE_NOTADB 
== code
); 
 491     if (dbconn
->isCorrupted
) { 
 492         /* Run integrity check and only make dbconn->isCorrupted true and 
 493            run the corruption handler if the integrity check conclusively fails. */ 
 494         dbconn
->maybeCorruptedCode 
= code
; 
 495         dbconn
->isCorrupted 
= SecDbCheckCorrupted(dbconn
); 
 496         if (dbconn
->isCorrupted
) { 
 497             secerror("operation returned code: %d integrity check=fail", code
); 
 498             (void)SecDbHandleCorrupt(dbconn
, code
, error
); 
 500             secerror("operation returned code: %d: integrity check=pass", code
); 
 507 #define BUSY_TIMEOUT_MS (5 * 60 * 1000)  /* 5 minutes */ 
 509 static int sleepBackoff
[] = { 10, 20, 50, 100, 250 }; 
 510 static int sumBackoff
[]   = { 10, 30, 80, 180, 430 }; 
 511 static int NumberOfSleepBackoff 
= sizeof(sleepBackoff
)/sizeof(sleepBackoff
[0]); 
 513 // Use these as silly hacks to encode the SQLite return code in the backtrace, for hang debugging purposes 
 514 static void __attribute__((noinline
)) SecDbLockSleep(int ms
) { 
 518 static void __attribute__((noinline
)) SecDbBusySleep(int ms
) { 
 522 // Return true causes the operation to be tried again. 
 523 // Note that we set sqlite3_busy_timeout on the connection, so anytime you're in here, it's likely due to SQLITE_LOCKED. 
 524 static bool SecDbWaitIfNeeded(SecDbConnectionRef dbconn
, int s3e
, sqlite3_stmt 
*stmt
, CFStringRef desc
, int nTries
, CFErrorRef 
*error
) { 
 525     if (((0xFF & s3e
) == SQLITE_BUSY
) || ((0xFF & s3e
) == SQLITE_LOCKED
)) { 
 526         int totaltimeout
, timeout
; 
 528         _Static_assert(sizeof(sumBackoff
) == sizeof(sleepBackoff
), "matching arrays not matching"); 
 529         _Static_assert(sizeof(sumBackoff
[0]) == sizeof(sleepBackoff
[0]), "matching arrays not matching"); 
 531         if (nTries 
< NumberOfSleepBackoff
) { 
 532             timeout 
= sleepBackoff
[nTries
]; 
 533             totaltimeout 
= sumBackoff
[nTries
]; 
 535             timeout 
= sleepBackoff
[NumberOfSleepBackoff 
- 1]; 
 536             totaltimeout 
= sumBackoff
[NumberOfSleepBackoff 
- 1] + (timeout 
* (nTries 
- NumberOfSleepBackoff
)); 
 538         if (totaltimeout 
< BUSY_TIMEOUT_MS
) { 
 539             secinfo("#SecDB", "sqlite busy/locked: %d ntries: %d totaltimeout: %d", s3e
, nTries
, totaltimeout
); 
 540             if(((0xFF & s3e
) == SQLITE_LOCKED
)) { 
 541                 SecDbLockSleep(timeout
); 
 543                 SecDbBusySleep(timeout
); 
 547             secinfo("#SecDB", "sqlite busy/locked: too long: %d ms, giving up", totaltimeout
); 
 551     return SecDbConnectionCheckCode(dbconn
, s3e
, error
, CFSTR("%@"), desc
); 
 554 enum SecDbStepResult 
{ 
 559 typedef enum SecDbStepResult SecDbStepResult
; 
 561 static SecDbStepResult 
_SecDbStep(SecDbConnectionRef dbconn
, sqlite3_stmt 
*stmt
, CFErrorRef 
*error
) { 
 562     assert(stmt 
!= NULL
); 
 566         if (SecDbConnectionIsReadOnly(dbconn
) && !sqlite3_stmt_readonly(stmt
)) { 
 567             secerror("_SecDbStep: SecDbConnection is readonly but we're about to write: %s", sqlite3_sql(stmt
)); 
 569         s3e 
= sqlite3_step(stmt
); 
 570         if (s3e 
== SQLITE_ROW
) { 
 571             return kSecDbRowStep
; 
 572         } else if (s3e 
== SQLITE_DONE
) { 
 574              ** ^[SQLITE_DONE] means that the statement has finished executing 
 575              ** successfully.  sqlite3_step() should not be called again on this virtual 
 576              ** machine without first calling [] to reset the virtual 
 577              ** machine back to its initial state. 
 580             return kSecDbDoneStep
; 
 581         } else if (!SecDbWaitIfNeeded(dbconn
, s3e
, stmt
, CFSTR("step"), ntries
, error
)) { 
 582             return kSecDbErrorStep
; 
 589 SecDbExec(SecDbConnectionRef dbconn
, CFStringRef sql
, CFErrorRef 
*error
) 
 594         CFStringRef tail 
= NULL
; 
 596             sqlite3_stmt 
*stmt 
= SecDbCopyStmt(dbconn
, sql
, &tail
, error
); 
 600                 while ((sr 
= _SecDbStep(dbconn
, stmt
, error
)) == kSecDbRowStep
); 
 601                 if (sr 
== kSecDbErrorStep
) 
 603                 ok 
&= SecDbReleaseCachedStmt(dbconn
, sql
, stmt
, error
); 
 606             // TODO We already have an error here we really just want the left over sql in it's userData 
 607             ok 
= SecDbError(SQLITE_ERROR
, error
, CFSTR("Error with unexecuted sql remaining %@"), sql
); 
 615 static int SecDBGetInteger(SecDbConnectionRef dbconn
, CFStringRef sql
) 
 617     __block 
int number 
= -1; 
 618     __block CFErrorRef error 
= NULL
; 
 620     (void)SecDbWithSQL(dbconn
, sql
, &error
, ^bool(sqlite3_stmt 
*sqlStmt
) { 
 621         (void)SecDbStep(dbconn
, sqlStmt
, &error
, ^(bool *stop
) { 
 622             number 
= sqlite3_column_int(sqlStmt
, 0); 
 627     CFReleaseNull(error
); 
 632 void SecDBManagementTasks(SecDbConnectionRef dbconn
) 
 634     int64_t page_count 
= SecDBGetInteger(dbconn
, CFSTR("pragma page_count")); 
 635     if (page_count 
<= 0) { 
 638     int64_t free_count 
= SecDBGetInteger(dbconn
, CFSTR("pragma freelist_count")); 
 639     if (free_count 
< 0) { 
 643     int64_t max_free 
= 8192; 
 645     int64_t pages_in_use 
= page_count 
- free_count
; 
 646     double loadFactor 
= ((double)pages_in_use
/(double)page_count
); 
 647     if (0.85 < loadFactor 
&& free_count 
< max_free
) { 
 650         int64_t pages_to_free 
= (int64_t)(0.2 * free_count
); 
 651         if (0.4 > loadFactor
) { 
 652             pages_to_free 
= free_count
; 
 655         char *formatString 
= NULL
; 
 656         asprintf(&formatString
, "pragma incremental_vacuum(%d)", (int)pages_to_free
); 
 658             char *sqlerror 
= NULL
; 
 659             int rc 
= sqlite3_exec(dbconn
->handle
, formatString
, NULL
, NULL
, &sqlerror
); 
 661                 secerror("incremental_vacuum failed with: (%d) %{public}s", rc
, sqlerror
); 
 663             sqlite3_free(sqlerror
); 
 670 static bool SecDbBeginTransaction(SecDbConnectionRef dbconn
, SecDbTransactionType type
, CFErrorRef 
*error
) 
 675         case kSecDbImmediateTransactionType
: 
 676             secdebug("db", "SecDbBeginTransaction SecDbBeginTransaction %p", dbconn
); 
 677             query 
= CFSTR("BEGIN IMMEDIATE"); 
 679         case kSecDbExclusiveRemoteSOSTransactionType
: 
 680             secdebug("db", "SecDbBeginTransaction kSecDbExclusiveRemoteSOSTransactionType %p", dbconn
); 
 681             dbconn
->source 
= kSecDbSOSTransaction
; 
 682             query 
= CFSTR("BEGIN EXCLUSIVE"); 
 684         case kSecDbExclusiveRemoteCKKSTransactionType
: 
 685             secdebug("db", "SecDbBeginTransaction kSecDbExclusiveRemoteCKKSTransactionType %p", dbconn
); 
 686             dbconn
->source 
= kSecDbCKKSTransaction
; 
 687             query 
= CFSTR("BEGIN EXCLUSIVE"); 
 689         case kSecDbExclusiveTransactionType
: 
 690             if (type
==kSecDbExclusiveTransactionType
) 
 691                 secdebug("db", "SecDbBeginTransaction kSecDbExclusiveTransactionType %p", dbconn
); 
 692             query 
= CFSTR("BEGIN EXCLUSIVE"); 
 694         case kSecDbNormalTransactionType
: 
 695             secdebug("db", "SecDbBeginTransaction kSecDbNormalTransactionType %p", dbconn
); 
 696             query 
= CFSTR("BEGIN"); 
 699             secdebug("db", "SecDbBeginTransaction invalid transaction type %lu", type
); 
 700             ok 
= SecDbError(SQLITE_ERROR
, error
, CFSTR("invalid transaction type %d"), (int)type
); 
 705     if (query 
!= NULL 
&& sqlite3_get_autocommit(dbconn
->handle
) != 0) { 
 706         ok 
= SecDbExec(dbconn
, query
, error
); 
 709         dbconn
->inTransaction 
= true; 
 714 static bool SecDbEndTransaction(SecDbConnectionRef dbconn
, bool commit
, CFErrorRef 
*error
) 
 716     __block 
bool ok 
= true; 
 717     __block 
bool commited 
= false; 
 719     dispatch_block_t notifyAndExec 
= ^{ 
 721             //secdebug("db", "SecDbEndTransaction kSecDbTransactionWillCommit %p", dbconn); 
 722             SecDbNotifyPhase(dbconn
, kSecDbTransactionWillCommit
); 
 723             commited 
= ok 
= SecDbExec(dbconn
, CFSTR("END"), error
); 
 724             //secdebug("db", "SecDbEndTransaction kSecDbTransactionWillCommit %p (after notify)", dbconn); 
 726             ok 
= SecDbExec(dbconn
, CFSTR("ROLLBACK"), error
); 
 729         dbconn
->inTransaction 
= false; 
 730         SecDbNotifyPhase(dbconn
, commited 
? kSecDbTransactionDidCommit 
: kSecDbTransactionDidRollback
); 
 731         secdebug("db", "SecDbEndTransaction %s %p", commited 
? "kSecDbTransactionDidCommit" : "kSecDbTransactionDidRollback", dbconn
); 
 732         dbconn
->source 
= kSecDbAPITransaction
; 
 734         if (commit 
&& dbconn
->db
->useRobotVacuum
) { 
 735             SecDBManagementTasks(dbconn
); 
 739     SecDbPerformOnCommitQueue(dbconn
, true, notifyAndExec
); 
 744 bool SecDbTransaction(SecDbConnectionRef dbconn
, SecDbTransactionType type
, 
 745                       CFErrorRef 
*error
, void (^transaction
)(bool *commit
)) 
 750     if (dbconn
->inTransaction
) { 
 751         transaction(&commit
); 
 753             secinfo("#SecDB", "#SecDB nested transaction asked to not be committed"); 
 756         ok 
= SecDbBeginTransaction(dbconn
, type
, error
); 
 758             transaction(&commit
); 
 759             ok 
= SecDbEndTransaction(dbconn
, commit
, error
); 
 766 sqlite3 
*SecDbHandle(SecDbConnectionRef dbconn
) { 
 767     return dbconn
->handle
; 
 770 bool SecDbStep(SecDbConnectionRef dbconn
, sqlite3_stmt 
*stmt
, CFErrorRef 
*error
, void (^row
)(bool *stop
)) { 
 772         switch (_SecDbStep(dbconn
, stmt
, error
)) { 
 773             case kSecDbErrorStep
: 
 774                 secdebug("db", "kSecDbErrorStep %@", error 
? *error 
: NULL
); 
 778                 secdebug("db", "kSecDbRowStep %@", error 
? *error 
: NULL
); 
 781                     __block 
bool stop 
= false; 
 782                     SecAutoreleaseInvokeWithPool(^{ 
 789                 SecDbError(SQLITE_ERROR
, error
, CFSTR("SecDbStep SQLITE_ROW returned without a row handler")); 
 793                 secdebug("db", "kSecDbDoneStep %@", error 
? *error 
: NULL
); 
 800 bool SecDbCheckpoint(SecDbConnectionRef dbconn
, CFErrorRef 
*error
) 
 802     return SecDbConnectionCheckCode(dbconn
, sqlite3_wal_checkpoint(dbconn
->handle
, NULL
), error
, CFSTR("wal_checkpoint")); 
 805 static sqlite3 
*_SecDbOpenV2(const char *path
, 
 810     sqlite3 
*handle 
= NULL
; 
 811     int s3e 
= sqlite3_open_v2(path
, &handle
, flags
, NULL
); 
 814             SecDbErrorWithDb(s3e
, handle
, error
, CFSTR("open_v2 \"%s\" 0x%X"), path
, flags
); 
 815             sqlite3_close(handle
); 
 818             SecDbError(s3e
, error
, CFSTR("open_v2 \"%s\" 0x%X"), path
, flags
); 
 820     } else if (SQLITE_OPEN_READWRITE 
== (flags 
& SQLITE_OPEN_READWRITE
)) { 
 821         if (useRobotVacuum
) { 
 822 #define SECDB_SQLITE_AUTO_VACUUM_INCREMENTAL 2 
 823             sqlite3_stmt 
*stmt 
= NULL
; 
 827              * Setting auto_vacuum = incremental on a database that is not empty requires 
 828              * a VACCUUM, so check if the vacuum mode is not INCREMENTAL, and if its not, 
 829              * set it to incremental and vacuum. 
 832             s3e 
= sqlite3_prepare_v2(handle
, "PRAGMA auto_vacuum", -1, &stmt
, NULL
); 
 834                 s3e 
= sqlite3_step(stmt
); 
 835                 if (s3e 
== SQLITE_ROW
) { 
 836                     vacuumMode 
= sqlite3_column_int(stmt
, 0); 
 838                 (void)sqlite3_finalize(stmt
); 
 841             if (vacuumMode 
!= SECDB_SQLITE_AUTO_VACUUM_INCREMENTAL
) { 
 842                 (void)sqlite3_exec(handle
, "PRAGMA auto_vacuum = incremental", NULL
, NULL
, NULL
); 
 843                 (void)sqlite3_exec(handle
, "VACUUM", NULL
, NULL
, NULL
); 
 847             (void)sqlite3_exec(handle
, "PRAGMA journal_mode = WAL", NULL
, NULL
, NULL
); 
 850         // Let SQLite handle timeouts. 
 851         sqlite3_busy_timeout(handle
, 5*1000); 
 856 static bool SecDbOpenV2(SecDbConnectionRef dbconn
, const char *path
, int flags
, CFErrorRef 
*error
) { 
 857     return (dbconn
->handle 
= _SecDbOpenV2(path
, flags
, dbconn
->db
->useWAL
, dbconn
->db
->useRobotVacuum
, error
)) != NULL
; 
 860 // This construction lets tests not exit here 
 861 static void SecDbProductionCorruptionExitHandler(void) 
 865 void (*SecDbCorruptionExitHandler
)(void) = SecDbProductionCorruptionExitHandler
; 
 867 void SecDbResetCorruptionExitHandler(void) 
 869     SecDbCorruptionExitHandler 
= SecDbProductionCorruptionExitHandler
; 
 873  There's not much to do in here because we should only ever be here when 
 874  SQLite tells us the DB is corrupt, or the DB is unrecoverable because of 
 875  some fatal logic problem. But we can't shoot it dead either due to client 
 876  connections. So, first we create a marker to tell ourselves things are bad, 
 877  then we'll die. When we come back up we'll notice the marker and remove the DB. 
 879 static bool SecDbHandleCorrupt(SecDbConnectionRef dbconn
, int rc
, CFErrorRef 
*error
) 
 881     if (!dbconn
->db
->allowRepair
) { 
 882         SecCFCreateErrorWithFormat(rc
, kSecErrnoDomain
, NULL
, error
, NULL
, 
 883                                    CFSTR("SecDbHandleCorrupt not allowed to repair, handled error: [%d] %s"), rc
, strerror(rc
)); 
 884         dbconn
->isCorrupted 
= false; 
 888     CFStringPerformWithCString(dbconn
->db
->db_path
, ^(const char *db_path
) { 
 889         char marker
[PATH_MAX
+1]; 
 890         snprintf(marker
, sizeof(marker
), "%s-iscorrupt", db_path
); 
 891         struct stat info 
= {}; 
 892         if (0 == stat(marker
, &info
)) { 
 893             secerror("SecDbHandleCorrupt: Tried to write corruption marker %s but one already exists", marker
); 
 896         FILE* file 
= fopen(marker
, "w"); 
 898             secerror("SecDbHandleCorrupt: Unable (%{darwin.errno}d) to create corruption marker %{public}s", errno
, marker
); 
 904     secwarning("SecDbHandleCorrupt: killing self so that successor might cleanly delete corrupt db"); 
 906     // Call through function pointer so tests can replace it and call a SecKeychainDbReset instead 
 907     SecDbCorruptionExitHandler(); 
 911 static bool SecDbProcessCorruptionMarker(CFStringRef db_path
) { 
 912     __block 
bool ok 
= true; 
 913     CFStringPerformWithCString(db_path
, ^(const char *db_path
) { 
 914         char marker
[PATH_MAX
+1]; 
 915         snprintf(marker
, sizeof(marker
), "%s-iscorrupt", db_path
); 
 916         struct stat info 
= {}; 
 917         int result 
= stat(marker
, &info
); 
 918         if (result 
!= 0 && errno 
== ENOENT
) { 
 920         } else if (result 
!= 0) { 
 921             secerror("SecDbSecDbProcessCorruptionMarker: Unable to check for corruption marker: %{darwin.errno}d", errno
); 
 925         secwarning("SecDbSecDbProcessCorruptionMarker: found corruption marker %s", marker
); 
 926         if (remove(marker
)) { 
 927             secerror("SecDbSecDbProcessCorruptionMarker: Unable (%{darwin.errno}d) to delete corruption marker", errno
); 
 929         } else if (remove(db_path
) && errno 
!= ENOENT
) {    // Not sure how we'd get ENOENT but it would suit us just fine 
 930             secerror("SecDbSecDbProcessCorruptionMarker: Unable (%{darwin.errno}d) to delete db %{public}s", errno
, db_path
); 
 933             secwarning("SecDbSecDbProcessCorruptionMarker: deleted corrupt db %{public}s", db_path
); 
 940 SecDbSetCorruptionReset(SecDbRef db
, void (^corruptionReset
)(void)) 
 942     if (db
->corruptionReset
) { 
 943         Block_release(db
->corruptionReset
); 
 944         db
->corruptionReset 
= NULL
; 
 946     if (corruptionReset
) { 
 947         db
->corruptionReset 
= Block_copy(corruptionReset
); 
 951 static bool SecDbLoggingEnabled(CFStringRef type
) 
 953     CFTypeRef profile 
= NULL
; 
 954     bool enabled 
= false; 
 956     if (csr_check(CSR_ALLOW_APPLE_INTERNAL
) != 0) 
 959     profile 
= (CFNumberRef
)CFPreferencesCopyValue(CFSTR("SQLProfile"), CFSTR("com.apple.security"), kCFPreferencesAnyUser
, kCFPreferencesAnyHost
); 
 964     if (CFGetTypeID(profile
) == CFBooleanGetTypeID()) { 
 965         enabled 
= CFBooleanGetValue((CFBooleanRef
)profile
); 
 966     } else if (CFGetTypeID(profile
) == CFNumberGetTypeID()) { 
 968         CFNumberGetValue(profile
, kCFNumberSInt32Type
, &num
); 
 972     CFReleaseSafe(profile
); 
 978 SecDbProfileMask(void) 
 980     static dispatch_once_t onceToken
; 
 981     static unsigned profile_mask 
= 0; 
 983     // sudo defaults write /Library/Preferences/com.apple.security SQLProfile -bool true 
 984     dispatch_once(&onceToken
, ^{ 
 985         if (SecDbLoggingEnabled(CFSTR("SQLProfile"))) 
 986             profile_mask 
= SQLITE_TRACE_PROFILE
; 
 988         profile_mask 
|= SQLITE_TRACE_STMT
; 
 990         if (SecDbLoggingEnabled(CFSTR("SQLTrace"))) 
 991             profile_mask 
= SQLITE_TRACE_STMT
; 
 993         if (SecDbLoggingEnabled(CFSTR("SQLRow"))) 
 994             profile_mask 
= SQLITE_TRACE_ROW
; 
 995         secinfo("#SecDB", "sqlDb: sql trace mask: 0x%08x", profile_mask
); 
1001 SecDbTraceV2(unsigned mask
, void *ctx
, void *p
, void *x
) { 
1002     SecDbConnectionRef dbconn __unused 
= ctx
; 
1005     const char *trace 
= "unknown"; 
1006     char *tofree 
= NULL
; 
1008     if (mask 
== SQLITE_TRACE_PROFILE
) 
1009         trace 
= sqlite3_sql(p
); 
1010     else if (mask 
== SQLITE_TRACE_STMT
) { 
1011         trace 
= sqlite3_sql(p
); 
1012     } else if (mask 
== SQLITE_TRACE_ROW
) { 
1013         trace 
= tofree 
= sqlite3_expanded_sql(p
); 
1016     secinfo("#SecDB", "#SecDB %{public}s", trace
); 
1018     sqlite3_free(tofree
); 
1025 static bool SecDbOpenHandle(SecDbConnectionRef dbconn
, bool *created
, CFErrorRef 
*error
) 
1027     __block 
bool ok 
= true; 
1029     // This is pretty terrible because now what? We know we have a corrupt DB 
1030     // and now we can't get rid of it. 
1031     if (!SecDbProcessCorruptionMarker(dbconn
->db
->db_path
)) { 
1032         SecCFCreateErrorWithFormat(errno
, kSecErrnoDomain
, NULL
, error
, NULL
, CFSTR("Unable to process corruption marker: %{darwin.errno}d"), errno
); 
1036     CFStringPerformWithCString(dbconn
->db
->db_path
, ^(const char *db_path
) { 
1037         int flags 
= (dbconn
->db
->readWrite
) ? SQLITE_OPEN_READWRITE 
: SQLITE_OPEN_READONLY
; 
1038         ok 
= created 
&& SecDbOpenV2(dbconn
, db_path
, flags
, NULL
); 
1042                 char *tmp 
= dirname((char *)db_path
); 
1044                     mode_t omode 
= dbconn
->db
->mode
; 
1045                     if (omode 
& S_IRUSR
) { omode 
|= S_IXUSR
; } // owner can read 
1046                     if (omode 
& S_IRGRP
) { omode 
|= S_IXGRP
; } // group can read 
1047                     if (omode 
& S_IROTH
) { omode 
|= S_IXOTH
; } // other can read 
1048                     int errnum 
= mkpath_np(tmp
, omode
); 
1049                     if (errnum 
!= 0 && errnum 
!= EEXIST
) { 
1050                         SecCFCreateErrorWithFormat(errnum
, kSecErrnoDomain
, NULL
, error
, NULL
, 
1051                                                    CFSTR("mkpath_np %s: [%d] %s"), tmp
, errnum
, strerror(errnum
)); 
1056             // if the enclosing directory is ok, try to create the database. 
1057             // this forces us to open it read-write, so we'll need to be the owner here. 
1058             ok 
= ok 
&& SecDbOpenV2(dbconn
, db_path
, SQLITE_OPEN_READWRITE 
| SQLITE_OPEN_CREATE
, error
); 
1060                 chmod(db_path
, dbconn
->db
->mode
); // default: 0600 (S_IRUSR | S_IWUSR) 
1067             unsigned mask 
= SecDbProfileMask(); 
1069                 (void)sqlite3_trace_v2(dbconn
->handle
, 
1080 static SecDbConnectionRef
 
1081 SecDbConnectionCreate(SecDbRef db
, bool readOnly
, CFErrorRef 
*error
) 
1083     SecDbConnectionRef dbconn 
= NULL
; 
1085     dbconn 
= CFTypeAllocate(SecDbConnection
, struct __OpaqueSecDbConnection
, kCFAllocatorDefault
); 
1086     require(dbconn 
!= NULL
, done
); 
1089     dbconn
->readOnly 
= readOnly
; 
1090     dbconn
->inTransaction 
= false; 
1091     dbconn
->source 
= kSecDbInvalidTransaction
; 
1092     dbconn
->isCorrupted 
= false; 
1093     dbconn
->maybeCorruptedCode 
= 0; 
1094     dbconn
->hasIOFailure 
= false; 
1095     dbconn
->corruptionError 
= NULL
; 
1096     dbconn
->handle 
= NULL
; 
1097     dbconn
->changes 
= CFArrayCreateMutableForCFTypes(kCFAllocatorDefault
); 
1103 bool SecDbConnectionIsReadOnly(SecDbConnectionRef dbconn
) { 
1104     return dbconn
->readOnly
; 
1107 static void SecDbConectionSetReadOnly(SecDbConnectionRef dbconn
, bool readOnly
) { 
1108     dbconn
->readOnly 
= readOnly
; 
1111 SecDbConnectionRef 
SecDbConnectionAcquire(SecDbRef db
, bool readOnly
, CFErrorRef 
*error
) { 
1112     SecDbConnectionRef dbconn 
= NULL
; 
1113     SecDbConnectionAcquireRefMigrationSafe(db
, readOnly
, &dbconn
, error
); 
1117 static void SecDbConnectionConsumeResource(SecDbRef db
, bool readOnly
) { 
1119         dispatch_semaphore_wait(db
->readSemaphore
, DISPATCH_TIME_FOREVER
); 
1121         pthread_mutex_lock(&(db
->writeMutex
)); 
1125 static void SecDbConnectionMakeResourceAvailable(SecDbRef db
, bool readOnly
) { 
1127         dispatch_semaphore_signal(db
->readSemaphore
); 
1129         pthread_mutex_unlock(&(db
->writeMutex
)); 
1133 bool SecDbConnectionAcquireRefMigrationSafe(SecDbRef db
, bool readOnly
, SecDbConnectionRef
* dbconnRef
, CFErrorRef 
*error
) 
1137     secinfo("dbconn", "acquire %s connection", readOnly 
? "ro" : "rw"); 
1139     SecDbConnectionConsumeResource(db
, readOnly
); 
1141     __block SecDbConnectionRef dbconn 
= NULL
; 
1142     __block 
bool ok 
= true; 
1143     __block 
bool ranOpenedHandler 
= false; 
1145     bool (^assignDbConn
)(SecDbConnectionRef
) = ^bool(SecDbConnectionRef connection
) { 
1146         dbconn 
= connection
; 
1148             *dbconnRef 
= connection
; 
1151         return dbconn 
!= NULL
; 
1154     dispatch_sync(db
->queue
, ^{ 
1155         if (!db
->didFirstOpen
) { 
1156             bool didCreate 
= false; 
1157             ok 
= assignDbConn(SecDbConnectionCreate(db
, false, error
)); 
1158             CFErrorRef localError 
= NULL
; 
1159             if (ok 
&& !SecDbOpenHandle(dbconn
, &didCreate
, &localError
)) { 
1160                 secerror("Unable to create database: %@", localError
); 
1161                 if (localError 
&& CFEqual(CFErrorGetDomain(localError
), kSecDbErrorDomain
)) { 
1162                     int code 
= (int)CFErrorGetCode(localError
); 
1163                     dbconn
->isCorrupted 
= (SQLITE_CORRUPT 
== code
) || (SQLITE_NOTADB 
== code
); 
1165                 // If the open failure isn't due to corruption, propagate the error. 
1166                 ok 
= dbconn
->isCorrupted
; 
1167                 if (!ok 
&& error 
&& *error 
== NULL
) { 
1168                     *error 
= localError
; 
1172             CFReleaseNull(localError
); 
1175                 db
->didFirstOpen 
= ok 
= SecDbDidCreateFirstConnection(dbconn
, didCreate
, error
); 
1176                 ranOpenedHandler 
= true; 
1177                 SecDbConectionSetReadOnly(dbconn
, readOnly
);    // first connection always created "rw", so set to real value 
1179                 CFReleaseNull(dbconn
); 
1182             /* Try to get one from the cache */ 
1183             CFMutableArrayRef cache 
= readOnly 
? db
->idleReadConnections 
: db
->idleWriteConnections
; 
1184             if (CFArrayGetCount(cache
) && !dbconn
) { 
1185                 if (assignDbConn((SecDbConnectionRef
)CFArrayGetValueAtIndex(cache
, 0))) { 
1186                     CFRetainSafe(dbconn
); 
1188                 CFArrayRemoveValueAtIndex(cache
, 0); 
1193     if (ok 
&& !dbconn
) { 
1194         /* Nothing found in cache, create a new connection */ 
1195         bool created 
= false; 
1196         if (assignDbConn(SecDbConnectionCreate(db
, readOnly
, error
)) && !SecDbOpenHandle(dbconn
, &created
, error
)) { 
1197             CFReleaseNull(dbconn
); 
1201     if (dbconn 
&& !ranOpenedHandler 
&& dbconn
->db
->opened
) { 
1202         dispatch_sync(db
->queue
, ^{ 
1203             if (dbconn
->db
->callOpenedHandlerForNextConnection
) { 
1204                 dbconn
->db
->callOpenedHandlerForNextConnection 
= false; 
1205                 if (!dbconn
->db
->opened(db
, dbconn
, false, &dbconn
->db
->callOpenedHandlerForNextConnection
, error
)) { 
1206                     if (!dbconn
->isCorrupted 
|| !SecDbHandleCorrupt(dbconn
, 0, error
)) { 
1207                         CFReleaseNull(dbconn
); 
1215         *dbconnRef 
= dbconn
; 
1219         // Caller doesn't get (to use) a connection so the backing synchronization primitive is available again 
1220         SecDbConnectionMakeResourceAvailable(db
, readOnly
); 
1224     return dbconn 
? true : false; 
1227 void SecDbConnectionRelease(SecDbConnectionRef dbconn
) { 
1229         secerror("SecDbConnectionRelease called with NULL dbconn"); 
1232     SecDbRef db 
= dbconn
->db
; 
1234     secinfo("dbconn", "release %@", dbconn
); 
1237     bool readOnly 
= SecDbConnectionIsReadOnly(dbconn
); 
1238     dispatch_sync(db
->queue
, ^{ 
1239         if (dbconn
->hasIOFailure
) { 
1240             // Something wrong on the file layer (e.g. revoked file descriptor for networked home) 
1241             secwarning("SecDbConnectionRelease: IO failure reported in connection, throwing away currently idle caches"); 
1242             // Any other checked-out connections are beyond our grasp. If they did not have IO failures they'll come back, 
1243             // otherwise this branch gets taken more than once and gradually those connections die off 
1244             CFArrayRemoveAllValues(db
->idleWriteConnections
); 
1245             CFArrayRemoveAllValues(db
->idleReadConnections
); 
1247             CFMutableArrayRef cache 
= readOnly 
? db
->idleReadConnections 
: db
->idleWriteConnections
; 
1248             CFIndex count 
= CFArrayGetCount(cache
); 
1249             if ((unsigned long)count 
< (readOnly 
? kSecDbMaxReaders 
: kSecDbMaxWriters
)) { 
1250                 CFArrayAppendValue(cache
, dbconn
); 
1252                 secerror("dbconn: did not expect to run out of room in the %s cache when releasing connection", readOnly 
? "ro" : "rw"); 
1257     // Signal after we have put the connection back in the pool of connections 
1258     SecDbConnectionMakeResourceAvailable(db
, readOnly
); 
1263 void SecDbReleaseAllConnections(SecDbRef db
) { 
1264     // Force all connections to be removed (e.g. file descriptor no longer valid) 
1266         secerror("called with NULL db"); 
1269     dispatch_sync(db
->queue
, ^{ 
1270         CFArrayRemoveAllValues(db
->idleReadConnections
); 
1271         CFArrayRemoveAllValues(db
->idleWriteConnections
); 
1275 static void onQueueSecDbForceCloseForCache(CFMutableArrayRef cache
) { 
1276     CFArrayForEach(cache
, ^(const void* ptr
) { 
1277         SecDbConnectionRef connection 
= (SecDbConnectionRef
)ptr
; 
1279         // this pointer is claimed to be nonretained 
1280         connection
->db 
= NULL
; 
1282         if(connection
->handle
) { 
1283             sqlite3_close(connection
->handle
); 
1284             connection
->handle 
= NULL
; 
1287     CFArrayRemoveAllValues(cache
); 
1290 // Please make sure you want to do this. Any use of the outstanding connections to this DB will cause a crash. 
1291 void SecDbForceClose(SecDbRef db
) { 
1292     dispatch_sync(db
->queue
, ^{ 
1293         onQueueSecDbForceCloseForCache(db
->idleReadConnections
); 
1294         onQueueSecDbForceCloseForCache(db
->idleWriteConnections
); 
1298 bool SecDbPerformRead(SecDbRef db
, CFErrorRef 
*error
, void (^perform
)(SecDbConnectionRef dbconn
)) { 
1299     SecDbConnectionRef dbconn 
= SecDbConnectionAcquire(db
, true, error
); 
1300     bool success 
= false; 
1304         SecDbConnectionRelease(dbconn
); 
1309 bool SecDbPerformWrite(SecDbRef db
, CFErrorRef 
*error
, void (^perform
)(SecDbConnectionRef dbconn
)) { 
1311         SecError(errSecNotAvailable
, error
, CFSTR("failed to get a db handle")); 
1314     SecDbConnectionRef dbconn 
= SecDbConnectionAcquire(db
, false, error
); 
1315     bool success 
= false; 
1319         SecDbConnectionRelease(dbconn
); 
1325 SecDbConnectionCopyFormatDescription(CFTypeRef value
, CFDictionaryRef formatOptions
) 
1327     SecDbConnectionRef dbconn 
= (SecDbConnectionRef
)value
; 
1328     return CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("<SecDbConnection %s %s>"), 
1329                                     dbconn
->readOnly 
? "ro" : "rw", dbconn
->handle 
? "open" : "closed"); 
1333 SecDbConnectionDestroy(CFTypeRef value
) 
1335     SecDbConnectionRef dbconn 
= (SecDbConnectionRef
)value
; 
1336     if (dbconn
->handle
) { 
1337         int s3e 
= sqlite3_close(dbconn
->handle
); 
1338         if (s3e 
!= SQLITE_OK
) { 
1339             secerror("failed to close database connection (%d) for %@: %s", s3e
, dbconn
->db
->db_path
, sqlite3_errmsg(dbconn
->handle
)); 
1341         os_assert(s3e 
== SQLITE_OK
); // Crash now or jetsam later 
1344     CFReleaseNull(dbconn
->changes
); 
1345     CFReleaseNull(dbconn
->corruptionError
); 
1349 void SecDbPerformOnCommitQueue(SecDbConnectionRef dbconn
, bool barrier
, dispatch_block_t perform
) { 
1351         dispatch_barrier_sync(dbconn
->db
->commitQueue
, ^{ 
1355         dispatch_sync(dbconn
->db
->commitQueue
, ^{ 
1362 // MARK: Bind helpers 
1364 // Logging binds is very spammy when debug logging is on (~90% of log lines), and isn't often useful. 
1365 // Enable this in your local build if you actually want every single SQL variable bind logged for debugging. 
1366 #define LOG_SECDB_BINDS 0 
1368 bool SecDbBindBlob(sqlite3_stmt 
*stmt
, int param
, const void *zData
, size_t n
, void(*xDel
)(void*), CFErrorRef 
*error
) { 
1370         return SecDbErrorWithStmt(SQLITE_TOOBIG
, stmt
, error
, 
1371                                   CFSTR("bind_blob[%d]: blob bigger than INT_MAX"), param
); 
1373     bool ok 
= SecDbErrorWithStmt(sqlite3_bind_blob(stmt
, param
, zData
, (int)n
, xDel
), 
1374                                  stmt
, error
, CFSTR("bind_blob[%d]"), param
); 
1376     secinfo("bind", "bind_blob[%d]: %.*P: %@", param
, (int)n
, zData
, error 
? *error 
: NULL
); 
1381 bool SecDbBindText(sqlite3_stmt 
*stmt
, int param
, const char *zData
, size_t n
, void(*xDel
)(void*), CFErrorRef 
*error
) { 
1383         return SecDbErrorWithStmt(SQLITE_TOOBIG
, stmt
, error
, 
1384                                   CFSTR("bind_text[%d]: text bigger than INT_MAX"), param
); 
1386     bool ok 
= SecDbErrorWithStmt(sqlite3_bind_text(stmt
, param
, zData
, (int)n
, xDel
), stmt
, error
, 
1387                                  CFSTR("bind_text[%d]"), param
); 
1389     secinfo("bind", "bind_text[%d]: \"%s\" error: %@", param
, zData
, error 
? *error 
: NULL
); 
1394 bool SecDbBindDouble(sqlite3_stmt 
*stmt
, int param
, double value
, CFErrorRef 
*error
) { 
1395     bool ok 
= SecDbErrorWithStmt(sqlite3_bind_double(stmt
, param
, value
), stmt
, error
, 
1396                                  CFSTR("bind_double[%d]"), param
); 
1398     secinfo("bind", "bind_double[%d]: %f error: %@", param
, value
, error 
? *error 
: NULL
); 
1403 bool SecDbBindInt(sqlite3_stmt 
*stmt
, int param
, int value
, CFErrorRef 
*error
) { 
1404     bool ok 
= SecDbErrorWithStmt(sqlite3_bind_int(stmt
, param
, value
), stmt
, error
, 
1405                                  CFSTR("bind_int[%d]"), param
); 
1407     secinfo("bind", "bind_int[%d]: %d error: %@", param
, value
, error 
? *error 
: NULL
); 
1412 bool SecDbBindInt64(sqlite3_stmt 
*stmt
, int param
, sqlite3_int64 value
, CFErrorRef 
*error
) { 
1413     bool ok 
= SecDbErrorWithStmt(sqlite3_bind_int64(stmt
, param
, value
), stmt
, error
, 
1414                                  CFSTR("bind_int64[%d]"), param
); 
1416     secinfo("bind", "bind_int64[%d]: %lld error: %@", param
, value
, error 
? *error 
: NULL
); 
1422 /* AUDIT[securityd](done): 
1423  value (ok) is a caller provided, non NULL CFTypeRef. 
1425 bool SecDbBindObject(sqlite3_stmt 
*stmt
, int param
, CFTypeRef value
, CFErrorRef 
*error
) { 
1427     __block 
bool result 
= false; 
1429         /* TODO: Can we use SQLITE_STATIC below everwhere we currently use 
1430      SQLITE_TRANSIENT since we finalize the statement before the value 
1431      goes out of scope? */ 
1432     if (!value 
|| (valueId 
= CFGetTypeID(value
)) == CFNullGetTypeID()) { 
1433         /* Skip bindings for NULL values.  sqlite3 will interpret unbound 
1434          params as NULL which is exactly what we want. */ 
1436     } else if (valueId 
== CFStringGetTypeID()) { 
1437         CFStringPerformWithCStringAndLength(value
, ^(const char *cstr
, size_t clen
) { 
1438             result 
= SecDbBindText(stmt
, param
, cstr
, clen
, SQLITE_TRANSIENT
, error
); 
1440     } else if (valueId 
== CFDataGetTypeID()) { 
1441         CFIndex len 
= CFDataGetLength(value
); 
1443             result 
= SecDbBindBlob(stmt
, param
, CFDataGetBytePtr(value
), 
1444                                    len
, SQLITE_TRANSIENT
, error
); 
1446             result 
= SecDbBindText(stmt
, param
, "", 0, SQLITE_TRANSIENT
, error
); 
1448     } else if (valueId 
== CFDateGetTypeID()) { 
1449         CFAbsoluteTime abs_time 
= CFDateGetAbsoluteTime(value
); 
1450         result 
= SecDbBindDouble(stmt
, param
, abs_time
, error
); 
1451     } else if (valueId 
== CFBooleanGetTypeID()) { 
1452         int bval 
= CFBooleanGetValue(value
); 
1453         result 
= SecDbBindInt(stmt
, param
, bval
, error
); 
1454     } else if (valueId 
== CFNumberGetTypeID()) { 
1456         if (CFNumberIsFloatType(value
)) { 
1458             convertOk 
= CFNumberGetValue(value
, kCFNumberDoubleType
, &nval
); 
1459             result 
= SecDbBindDouble(stmt
, param
, nval
, error
); 
1461             sqlite_int64 nval64
; 
1462             convertOk 
= CFNumberGetValue(value
, kCFNumberSInt64Type
, &nval64
); 
1464                 result 
= SecDbBindInt64(stmt
, param
, nval64
, error
); 
1468             result 
= SecDbError(SQLITE_INTERNAL
, error
, CFSTR("bind CFNumberGetValue failed for %@"), value
); 
1472             CFStringRef valueDesc 
= CFCopyTypeIDDescription(valueId
); 
1473             SecDbError(SQLITE_MISMATCH
, error
, CFSTR("bind unsupported type %@"), valueDesc
); 
1474             CFReleaseSafe(valueDesc
); 
1482 // MARK: SecDbStatementRef 
1484 bool SecDbReset(sqlite3_stmt 
*stmt
, CFErrorRef 
*error
) { 
1485     return SecDbErrorWithStmt(sqlite3_reset(stmt
), stmt
, error
, CFSTR("reset")); 
1488 bool SecDbClearBindings(sqlite3_stmt 
*stmt
, CFErrorRef 
*error
) { 
1489     return SecDbErrorWithStmt(sqlite3_clear_bindings(stmt
), stmt
, error
, CFSTR("clear bindings")); 
1492 bool SecDbFinalize(sqlite3_stmt 
*stmt
, CFErrorRef 
*error
) { 
1493     sqlite3 
*handle 
= sqlite3_db_handle(stmt
); 
1494     int s3e 
= sqlite3_finalize(stmt
); 
1495     return s3e 
== SQLITE_OK 
? true : SecDbErrorWithDb(s3e
, handle
, error
, CFSTR("finalize: %p"), stmt
); 
1498 sqlite3_stmt 
*SecDbPrepareV2(SecDbConnectionRef dbconn
, const char *sql
, size_t sqlLen
, const char **sqlTail
, CFErrorRef 
*error
) { 
1499     sqlite3 
*db 
= SecDbHandle(dbconn
); 
1500     if (sqlLen 
> INT_MAX
) { 
1501         SecDbErrorWithDb(SQLITE_TOOBIG
, db
, error
, CFSTR("prepare_v2: sql bigger than INT_MAX")); 
1506         sqlite3_stmt 
*stmt 
= NULL
; 
1507         int s3e 
= sqlite3_prepare_v2(db
, sql
, (int)sqlLen
, &stmt
, sqlTail
); 
1508         if (s3e 
== SQLITE_OK
) 
1510         else if (!SecDbWaitIfNeeded(dbconn
, s3e
, NULL
, CFSTR("preparev2"), ntries
, error
)) 
1516 static sqlite3_stmt 
*SecDbCopyStatementWithTailRange(SecDbConnectionRef dbconn
, CFStringRef sql
, CFRange 
*sqlTail
, CFErrorRef 
*error
) { 
1517     __block sqlite3_stmt 
*stmt 
= NULL
; 
1518     if (sql
) CFStringPerformWithCStringAndLength(sql
, ^(const char *sqlStr
, size_t sqlLen
) { 
1519         const char *tail 
= NULL
; 
1520         stmt 
= SecDbPrepareV2(dbconn
, sqlStr
, sqlLen
, &tail
, error
); 
1521         if (sqlTail 
&& sqlStr 
< tail 
&& tail 
< sqlStr 
+ sqlLen
) { 
1522             sqlTail
->location 
= tail 
- sqlStr
; 
1523             sqlTail
->length 
= sqlLen 
- sqlTail
->location
; 
1530 sqlite3_stmt 
*SecDbCopyStmt(SecDbConnectionRef dbconn
, CFStringRef sql
, CFStringRef 
*tail
, CFErrorRef 
*error
) { 
1531     // TODO: Add caching and cache lookup of statements 
1532     CFRange sqlTail 
= {}; 
1533     sqlite3_stmt 
*stmt 
= SecDbCopyStatementWithTailRange(dbconn
, sql
, &sqlTail
, error
); 
1534     if (sqlTail
.length 
> 0) { 
1535         CFStringRef excess 
= CFStringCreateWithSubstring(CFGetAllocator(sql
), sql
, sqlTail
); 
1539             SecDbError(SQLITE_INTERNAL
, error
, 
1540                        CFSTR("prepare_v2: %@ unused sql: %@"), 
1542             CFReleaseSafe(excess
); 
1543             SecDbFinalize(stmt
, error
); 
1551  TODO: Could do a hack here with a custom kCFAllocatorNULL allocator for a second CFRuntimeBase inside a SecDbStatement, 
1552  TODO: Better yet make a full blow SecDbStatement instance whenever SecDbCopyStmt is called.  Then, when the statement is released, in the Dispose method, we Reset and ClearBindings the sqlite3_stmt * and hand it back to the SecDb with the original CFStringRef for the sql (or hash thereof) as an argument. */ 
1553 bool SecDbReleaseCachedStmt(SecDbConnectionRef dbconn
, CFStringRef sql
, sqlite3_stmt 
*stmt
, CFErrorRef 
*error
) { 
1555         return SecDbFinalize(stmt
, error
); 
1560 bool SecDbPrepare(SecDbConnectionRef dbconn
, CFStringRef sql
, CFErrorRef 
*error
, void(^exec
)(sqlite3_stmt 
*stmt
)) { 
1561     assert(sql 
!= NULL
); 
1562     sqlite3_stmt 
*stmt 
= SecDbCopyStmt(dbconn
, sql
, NULL
, error
); 
1567     return SecDbReleaseCachedStmt(dbconn
, sql
, stmt
, error
); 
1570 bool SecDbWithSQL(SecDbConnectionRef dbconn
, CFStringRef sql
, CFErrorRef 
*error
, bool(^perform
)(sqlite3_stmt 
*stmt
)) { 
1574         CFStringRef tail 
= NULL
; 
1576             sqlite3_stmt 
*stmt 
= SecDbCopyStmt(dbconn
, sql
, &tail
, error
); 
1582                     // TODO: Use a different error scope here. 
1583                     ok 
= SecError(-50 /* errSecParam */, error
, CFSTR("SecDbWithSQL perform block missing")); 
1585                 ok 
&= SecDbReleaseCachedStmt(dbconn
, sql
, stmt
, error
); 
1588             // TODO We already have an error here we really just want the left over sql in it's userData 
1589             ok 
= SecDbError(SQLITE_ERROR
, error
, CFSTR("Error with unexecuted sql remaining %@"), sql
); 
1597 /* SecDbForEach returns true if all SQLITE_ROW returns of sqlite3_step() return true from the row block. 
1598  If the row block returns false and doesn't set an error (to indicate it has reached a limit), 
1599  this entire function returns false. In that case no error will be set. */ 
1600 bool SecDbForEach(SecDbConnectionRef dbconn
, sqlite3_stmt 
*stmt
, CFErrorRef 
*error
, bool(^row
)(int row_index
)) { 
1601     bool result 
= false; 
1602     for (int row_ix 
= 0;;++row_ix
) { 
1603         if (SecDbConnectionIsReadOnly(dbconn
) && !sqlite3_stmt_readonly(stmt
)) { 
1604             secerror("SecDbForEach: SecDbConnection is readonly but we're about to write: %s", sqlite3_sql(stmt
)); 
1606         int s3e 
= sqlite3_step(stmt
); 
1607         if (s3e 
== SQLITE_ROW
) { 
1613                 // If we have no row block then getting SQLITE_ROW is an error 
1614                 SecDbError(s3e
, error
, 
1615                            CFSTR("step[%d]: %s returned SQLITE_ROW with NULL row block"), 
1616                            row_ix
, sqlite3_sql(stmt
)); 
1619             if (s3e 
== SQLITE_DONE
) { 
1622                 SecDbConnectionCheckCode(dbconn
, s3e
, error
, CFSTR("SecDbForEach step[%d]"), row_ix
); 
1630 void SecDbRecordChange(SecDbConnectionRef dbconn
, CFTypeRef deleted
, CFTypeRef inserted
) { 
1631     if (!dbconn
->db
->notifyPhase
) return; 
1632     CFTypeRef entry 
= SecDbEventCreateWithComponents(deleted
, inserted
); 
1634         CFArrayAppendValue(dbconn
->changes
, entry
); 
1637         if (!dbconn
->inTransaction
) { 
1638             secerror("db %@ changed outside txn", dbconn
); 
1639             // Only notify of DidCommit, since WillCommit code assumes 
1641             SecDbOnNotify(dbconn
, ^{ 
1642                 SecDbNotifyPhase(dbconn
, kSecDbTransactionDidCommit
); 
1649 CFGiblisFor(SecDbConnection
) 
1652 // SecDbEvent Creation and consumption 
1655 static SecDbEventRef 
SecDbEventCreateInsert(CFTypeRef inserted
) { 
1656     return CFRetainSafe(inserted
); 
1659 static SecDbEventRef 
SecDbEventCreateDelete(CFTypeRef deleted
) { 
1660     return CFArrayCreate(kCFAllocatorDefault
, &deleted
, 1, &kCFTypeArrayCallBacks
); 
1663 static SecDbEventRef 
SecDbEventCreateUpdate(CFTypeRef deleted
, CFTypeRef inserted
) { 
1664     const void *values
[2] = { deleted
, inserted 
}; 
1665     return CFArrayCreate(kCFAllocatorDefault
, values
, 2, &kCFTypeArrayCallBacks
); 
1668 SecDbEventRef 
SecDbEventCreateWithComponents(CFTypeRef deleted
, CFTypeRef inserted
) { 
1669     if (deleted 
&& inserted
) 
1670         return SecDbEventCreateUpdate(deleted
, inserted
); 
1672         return SecDbEventCreateDelete(deleted
); 
1674         return SecDbEventCreateInsert(inserted
); 
1679 void SecDbEventTranslateComponents(SecDbEventRef item
, CFTypeRef
* deleted
, CFTypeRef
* inserted
) { 
1680     if(CFGetTypeID(item
) == CFArrayGetTypeID()) { 
1681         // One item: deletion. Two: update. 
1682         CFIndex arraySize 
= CFArrayGetCount(item
); 
1683         if(arraySize 
== 1) { 
1684             if(deleted
) { *deleted 
= CFArrayGetValueAtIndex(item
, 0); } 
1685             if(inserted
) { *inserted 
= NULL
; } 
1686         } else if(arraySize 
== 2) { 
1687             if(deleted
) { *deleted 
= CFArrayGetValueAtIndex(item
, 0); } 
1688             if(inserted
) { *inserted 
= CFArrayGetValueAtIndex(item
, 1); } 
1690             if(deleted
) { *deleted 
= NULL
; } 
1691             if(inserted
) { *inserted 
= NULL
; } 
1694         if(deleted
) { *deleted 
= NULL
; } 
1695         if(inserted
) { *inserted 
= item
; } 
1700 bool SecDbEventGetComponents(SecDbEventRef event
, CFTypeRef 
*deleted
, CFTypeRef 
*inserted
, CFErrorRef 
*error
) { 
1701     if (isArray(event
)) { 
1702         CFArrayRef array 
= event
; 
1703         switch (CFArrayGetCount(array
)) { 
1705                 *deleted 
= CFArrayGetValueAtIndex(array
, 0); 
1706                 *inserted 
= CFArrayGetValueAtIndex(array
, 1); 
1709                 *deleted 
= CFArrayGetValueAtIndex(array
, 0); 
1713                 SecError(errSecParam
, error
, NULL
, CFSTR("invalid entry in changes array: %@"), array
);