Bug 188029 - Speculative fix for StorageProcess crash
Summary: Speculative fix for StorageProcess crash
Status: RESOLVED INVALID
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Alex Christensen
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-07-25 16:32 PDT by Alex Christensen
Modified: 2022-02-08 16:29 PST (History)
6 users (show)

See Also:


Attachments
Patch (2.88 KB, patch)
2018-07-25 16:34 PDT, Alex Christensen
cdumez: review-
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Alex Christensen 2018-07-25 16:32:24 PDT
Speculative fix for StorageProcess crash
Comment 1 Alex Christensen 2018-07-25 16:34:56 PDT
Created attachment 345801 [details]
Patch
Comment 2 Chris Dumez 2018-07-25 16:42:11 PDT
Comment on attachment 345801 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=345801&action=review

I am not in favor of making such a change:
1. We do not know for sure this is related to threading.
2. AFAIK, UniqueIDBDatabaseConnection should not be dealt with from non-main thread, they are not even ThreadSafeRefCounted

If we suspect threading, I think we should look at call sites. Also, adding the isMainThread() assertions is a good idea (maybe even release assertions?).

> Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.h:87
> +    Lock m_databaseConnectionsLock;

What about IDBConnectionToClient::connectionToClientClosed() ? You're failing to lock there so the Lock is not useful.
Comment 3 Chris Dumez 2018-07-25 16:45:16 PDT
Also, this does not look safe:
void IDBConnectionToClient::connectionToClientClosed()
{
    auto databaseConnections = m_databaseConnections;

    for (auto connection : databaseConnections) {
        if (m_databaseConnections.contains(connection))
            connection->connectionClosedFromClient();
    }

    m_databaseConnections.clear();
}

databaseConnections is a Vector of raw pointers. I am assuming we're copying m_databaseConnections to a vector before looping because m_databaseConnections may change while we iterate. If databaseConnection objects get destroyed while we iterate, we'll use a stale pointer and crash, despite us copying.
Comment 4 Chris Dumez 2018-07-25 16:46:17 PDT
(In reply to Chris Dumez from comment #3)
> Also, this does not look safe:
> void IDBConnectionToClient::connectionToClientClosed()
> {
>     auto databaseConnections = m_databaseConnections;
> 
>     for (auto connection : databaseConnections) {
>         if (m_databaseConnections.contains(connection))
>             connection->connectionClosedFromClient();
>     }
> 
>     m_databaseConnections.clear();
> }
> 
> databaseConnections is a Vector of raw pointers. I am assuming we're copying
> m_databaseConnections to a vector before looping because
> m_databaseConnections may change while we iterate. If databaseConnection
> objects get destroyed while we iterate, we'll use a stale pointer and crash,
> despite us copying.

We may want:
auto databaseConnections = copyToVectorOf<RefPtr<UniqueIDBDatabaseConnection>>(m_databaseConnections);
Comment 5 Chris Dumez 2018-07-26 09:55:24 PDT
(In reply to Chris Dumez from comment #4)
> (In reply to Chris Dumez from comment #3)
> > Also, this does not look safe:
> > void IDBConnectionToClient::connectionToClientClosed()
> > {
> >     auto databaseConnections = m_databaseConnections;
> > 
> >     for (auto connection : databaseConnections) {
> >         if (m_databaseConnections.contains(connection))
> >             connection->connectionClosedFromClient();
> >     }
> > 
> >     m_databaseConnections.clear();
> > }
> > 
> > databaseConnections is a Vector of raw pointers. I am assuming we're copying
> > m_databaseConnections to a vector before looping because
> > m_databaseConnections may change while we iterate. If databaseConnection
> > objects get destroyed while we iterate, we'll use a stale pointer and crash,
> > despite us copying.
> 
> We may want:
> auto databaseConnections =
> copyToVectorOf<RefPtr<UniqueIDBDatabaseConnection>>(m_databaseConnections);

Actually, it appears to be safe. The following check:
if (m_databaseConnections.contains(connection))

should make sure that the connection is still alive since the connection destructor would have removed it from m_databaseConnections.
Comment 6 Sihui Liu 2022-02-08 16:29:38 PST
StorageProcess does not exist now.