Title: [287322] trunk/Source/WebKit
Revision
287322
Author
[email protected]
Date
2021-12-21 10:31:16 -0800 (Tue, 21 Dec 2021)

Log Message

Harden PCM and ITP databases against crashes
https://bugs.webkit.org/show_bug.cgi?id=234528
<rdar://problem/86741319>

Reviewed by Brent Fulgham.

This patch does two things. First, it specifies a column type for the
new destination token, keyID and signature columns. This was causing
the crashes in rdar://86347439 by comparing the defined CREATE TABLE query
with types to the existing query with no types. Second, it adds
hardening to the migration code to abort migration if one of the steps
fails. This will help prevent future crashes like rdar://86347439
by aborting a migration early if a failure occurs and not leaving the
db in a messy state.

No new tests. No behavior change, this will harden against flaky issues
that may cause a migration to fail part way through, like I/O errors.

* NetworkProcess/DatabaseUtilities.cpp:
(WebKit::DatabaseUtilities::migrateDataToNewTablesIfNecessary):
* NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDatabase.cpp:
(WebKit::PCM::Database::addDestinationTokenColumnsIfNecessary):

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (287321 => 287322)


--- trunk/Source/WebKit/ChangeLog	2021-12-21 18:17:38 UTC (rev 287321)
+++ trunk/Source/WebKit/ChangeLog	2021-12-21 18:31:16 UTC (rev 287322)
@@ -1,3 +1,28 @@
+2021-12-21  Kate Cheney  <[email protected]>
+
+        Harden PCM and ITP databases against crashes
+        https://bugs.webkit.org/show_bug.cgi?id=234528
+        <rdar://problem/86741319>
+
+        Reviewed by Brent Fulgham.
+
+        This patch does two things. First, it specifies a column type for the
+        new destination token, keyID and signature columns. This was causing
+        the crashes in rdar://86347439 by comparing the defined CREATE TABLE query
+        with types to the existing query with no types. Second, it adds
+        hardening to the migration code to abort migration if one of the steps
+        fails. This will help prevent future crashes like rdar://86347439
+        by aborting a migration early if a failure occurs and not leaving the
+        db in a messy state.
+
+        No new tests. No behavior change, this will harden against flaky issues
+        that may cause a migration to fail part way through, like I/O errors.
+
+        * NetworkProcess/DatabaseUtilities.cpp:
+        (WebKit::DatabaseUtilities::migrateDataToNewTablesIfNecessary):
+        * NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDatabase.cpp:
+        (WebKit::PCM::Database::addDestinationTokenColumnsIfNecessary):
+
 2021-12-21  Wenson Hsieh  <[email protected]>
 
         Add support for a UI delegate method to decide how to handle detected modal containers

Modified: trunk/Source/WebKit/NetworkProcess/DatabaseUtilities.cpp (287321 => 287322)


--- trunk/Source/WebKit/NetworkProcess/DatabaseUtilities.cpp	2021-12-21 18:17:38 UTC (rev 287321)
+++ trunk/Source/WebKit/NetworkProcess/DatabaseUtilities.cpp	2021-12-21 18:31:16 UTC (rev 287322)
@@ -273,15 +273,18 @@
 
 void DatabaseUtilities::migrateDataToNewTablesIfNecessary()
 {
+    ASSERT(!RunLoop::isMain());
     if (!needsUpdatedSchema())
         return;
 
-    auto transactionScope = beginTransactionIfNecessary();
+    WebCore::SQLiteTransaction transaction(m_database);
+    transaction.begin();
 
     for (auto& table : expectedTableAndIndexQueries().keys()) {
         auto alterTable = m_database.prepareStatementSlow(makeString("ALTER TABLE ", table, " RENAME TO _", table));
         if (!alterTable || alterTable->step() != SQLITE_DONE) {
             RELEASE_LOG_ERROR(PrivateClickMeasurement, "%p - DatabaseUtilities::migrateDataToNewTablesIfNecessary failed to rename table, error message: %s", this, m_database.lastErrorMsg());
+            transaction.rollback();
             ASSERT_NOT_REACHED();
             return;
         }
@@ -288,6 +291,7 @@
     }
 
     if (!createSchema()) {
+        transaction.rollback();
         ASSERT_NOT_REACHED();
         return;
     }
@@ -296,6 +300,7 @@
     for (auto& table : sortedTables()) {
         auto migrateTableData = insertDistinctValuesInTableStatement(m_database, table);
         if (!migrateTableData || migrateTableData->step() != SQLITE_DONE) {
+            transaction.rollback();
             RELEASE_LOG_ERROR(PrivateClickMeasurement, "%p - DatabaseUtilities::migrateDataToNewTablesIfNecessary (table %s) failed to migrate schema, error message: %s", this, table.characters(), m_database.lastErrorMsg());
             ASSERT_NOT_REACHED();
             return;
@@ -306,6 +311,7 @@
     for (auto& table : sortedTables()) {
         auto dropTableQuery = m_database.prepareStatementSlow(makeString("DROP TABLE _", table));
         if (!dropTableQuery || dropTableQuery->step() != SQLITE_DONE) {
+            transaction.rollback();
             RELEASE_LOG_ERROR(PrivateClickMeasurement, "%p - DatabaseUtilities::migrateDataToNewTablesIfNecessary failed to drop temporary tables, error message: %s", this, m_database.lastErrorMsg());
             ASSERT_NOT_REACHED();
             return;
@@ -314,8 +320,12 @@
 
     if (!createUniqueIndices()) {
         RELEASE_LOG_ERROR(PrivateClickMeasurement, "%p - DatabaseUtilities::migrateDataToNewTablesIfNecessary failed to create unique indices, error message: %s", this, m_database.lastErrorMsg());
+        transaction.rollback();
         ASSERT_NOT_REACHED();
+        return;
     }
+
+    transaction.commit();
 }
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDatabase.cpp (287321 => 287322)


--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDatabase.cpp	2021-12-21 18:17:38 UTC (rev 287321)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDatabase.cpp	2021-12-21 18:31:16 UTC (rev 287322)
@@ -715,9 +715,9 @@
     String destinationKeyIDColumnName("destinationKeyID"_s);
     auto columns = columnsForTable(attributedTableName);
     if (!columns.size() || columns.last() != destinationKeyIDColumnName) {
-        addMissingColumnToTable(attributedTableName, "destinationToken"_s);
-        addMissingColumnToTable(attributedTableName, "destinationSignature"_s);
-        addMissingColumnToTable(attributedTableName, destinationKeyIDColumnName);
+        addMissingColumnToTable(attributedTableName, "destinationToken TEXT"_s);
+        addMissingColumnToTable(attributedTableName, "destinationSignature TEXT"_s);
+        addMissingColumnToTable(attributedTableName, "destinationKeyID TEXT");
     }
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to