Bug 1752466 Comment 54 Edit History

Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.

Johnny's comment comment 52 is right.  I made a PoC to prove calling `SHGetFolderPathW` in `DllMain` can cause a deadlock.  This proves this is not a problem on Firefox side.

The reason is that `windows_storage!kfapi::CFolderCache::GetPath` owns a critical section and then starts delayloading shcore.dll as shown below.  Preloading shcore.dll may resolve this deadlock, but in general, `DllMain` should not call this kind of expensive APIs.

Here's the flow of this deadlock.

1. FF's main thread calls `GetShellFolderPath` and owns the critical section
2. FF's main thread starts delayloading shcore.dll
3. WebRoot spawns a thread in FF that loads WRusr.dll
4. WRusr.dll's `DllMain` calls `SHGetFolderPathW`
5. WRusr.dll's `DllMain` waits for the critical section that is owned by FF's main thread
6. FF's main thread waits until loading shcore.dll is completed, but it's never completed because WRusr.dll's DllMain is running

```
windows_storage!kfapi::CFolderCache::GetPath+0xd0:
00007ffc`4d68f6c0 89542440        mov     dword ptr [rsp+40h],edx
00007ffc`4d68f6c4 498d742458      lea     rsi,[r12+58h]
00007ffc`4d68f6c9 488bce          mov     rcx,rsi
00007ffc`4d68f6cc 48ff155ddc5000  call    qword ptr [windows_storage!_imp_EnterCriticalSection (00007ffc`4db9d330)]
    ----> probably this is to protect a global counter below
00007ffc`4d68f6d3 0f1f440000      nop     dword ptr [rax+rax]
00007ffc`4d68f6d8 418b4c2418      mov     ecx,dword ptr [r12+18h]
00007ffc`4d68f6dd 48ff152cf06600  call    qword ptr [windows_storage!_imp_SHGlobalCounterGetValue (00007ffc`4dcfe710)]
    ----> delayloads shcore.dll
00007ffc`4d68f6e4 0f1f440000      nop     dword ptr [rax+rax]
00007ffc`4d68f6e9 413944241c      cmp     dword ptr [r12+1Ch],eax
00007ffc`4d68f6ee 0f85a10a0000    jne     windows_storage!kfapi::CFolderCache::GetPath+0xba5 (00007ffc`4d690195)

windows_storage!kfapi::CFolderCache::GetPath+0x104:
00007ffc`4d68f6f4 4032ff          xor     dil,dil

windows_storage!kfapi::CFolderCache::GetPath+0x107:
00007ffc`4d68f6f7 418944241c      mov     dword ptr [r12+1Ch],eax
00007ffc`4d68f6fc 418b4c2420      mov     ecx,dword ptr [r12+20h]
00007ffc`4d68f701 48ff1508f06600  call    qword ptr [windows_storage!_imp_SHGlobalCounterGetValue (00007ffc`4dcfe710)]
...

windows_storage!kfapi::CFolderCache::GetPath+0xba5:
00007ffc`4d690195 40b701          mov     dil,1
00007ffc`4d690198 e95af5ffff      jmp     windows_storage!kfapi::CFolderCache::GetPath+0x107 (00007ffc`4d68f6f7)
```
Johnny's comment 52 is right.  I made a PoC to prove calling `SHGetFolderPathW` in `DllMain` can cause a deadlock.  This proves this is not a problem on Firefox side.

The reason is that `windows_storage!kfapi::CFolderCache::GetPath` owns a critical section and then starts delayloading shcore.dll as shown below.  Preloading shcore.dll may resolve this deadlock, but in general, `DllMain` should not call this kind of expensive APIs.

Here's the flow of this deadlock.

1. FF's main thread calls `GetShellFolderPath` and owns the critical section
2. FF's main thread starts delayloading shcore.dll
3. WebRoot spawns a thread in FF that loads WRusr.dll
4. WRusr.dll's `DllMain` calls `SHGetFolderPathW`
5. WRusr.dll's `DllMain` waits for the critical section that is owned by FF's main thread
6. FF's main thread waits until loading shcore.dll is completed, but it's never completed because WRusr.dll's DllMain is running

```
windows_storage!kfapi::CFolderCache::GetPath+0xd0:
00007ffc`4d68f6c0 89542440        mov     dword ptr [rsp+40h],edx
00007ffc`4d68f6c4 498d742458      lea     rsi,[r12+58h]
00007ffc`4d68f6c9 488bce          mov     rcx,rsi
00007ffc`4d68f6cc 48ff155ddc5000  call    qword ptr [windows_storage!_imp_EnterCriticalSection (00007ffc`4db9d330)]
    ----> probably this is to protect a global counter below
00007ffc`4d68f6d3 0f1f440000      nop     dword ptr [rax+rax]
00007ffc`4d68f6d8 418b4c2418      mov     ecx,dword ptr [r12+18h]
00007ffc`4d68f6dd 48ff152cf06600  call    qword ptr [windows_storage!_imp_SHGlobalCounterGetValue (00007ffc`4dcfe710)]
    ----> delayloads shcore.dll
00007ffc`4d68f6e4 0f1f440000      nop     dword ptr [rax+rax]
00007ffc`4d68f6e9 413944241c      cmp     dword ptr [r12+1Ch],eax
00007ffc`4d68f6ee 0f85a10a0000    jne     windows_storage!kfapi::CFolderCache::GetPath+0xba5 (00007ffc`4d690195)

windows_storage!kfapi::CFolderCache::GetPath+0x104:
00007ffc`4d68f6f4 4032ff          xor     dil,dil

windows_storage!kfapi::CFolderCache::GetPath+0x107:
00007ffc`4d68f6f7 418944241c      mov     dword ptr [r12+1Ch],eax
00007ffc`4d68f6fc 418b4c2420      mov     ecx,dword ptr [r12+20h]
00007ffc`4d68f701 48ff1508f06600  call    qword ptr [windows_storage!_imp_SHGlobalCounterGetValue (00007ffc`4dcfe710)]
...
windows_storage!kfapi::CFolderCache::GetPath+0xba5:
00007ffc`4d690195 40b701          mov     dil,1
00007ffc`4d690198 e95af5ffff      jmp     windows_storage!kfapi::CFolderCache::GetPath+0x107 (00007ffc`4d68f6f7)
```

Back to Bug 1752466 Comment 54