[Bug 21232] Chromium-based browser engines (Chrome, Opera) crash on startup unless '--no-sandbox' is used (native API sandboxing/hooking scheme incompatible with Wine)

wine-bugs at winehq.org wine-bugs at winehq.org
Sun Aug 31 03:35:46 CDT 2014


https://bugs.winehq.org/show_bug.cgi?id=21232

Anastasius Focht <focht at gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |obfuscation
             Status|NEW                         |RESOLVED
          Component|-unknown                    |ntdll
         Resolution|---                         |WONTFIX
            Summary|Chrome crashes on startup   |Chromium-based browser
                   |unless '--no-sandbox' is    |engines (Chrome, Opera)
                   |used                        |crash on startup unless
                   |                            |'--no-sandbox' is used
                   |                            |(native API
                   |                            |sandboxing/hooking scheme
                   |                            |incompatible with Wine)

--- Comment #7 from Anastasius Focht <focht at gmx.net> ---
Hello folks,

confirming.

Chrome uses usermode syscall (native API) hooking to implement sandboxing.
The hooking code makes assumptions about the NT syscall API entries which Wine
can't implement for obvious reasons.

--- snip ---
info process
 pid      threads  executable (all id:s are in hex)
 00000022 1        'GoogleChromePortable.exe'
 00000024 70       \_ 'chrome.exe'
--- snip ---

--- snip ---
$ WINEDEBUG=+tid,+seh,+loaddll,+process,+module,+virtual,+server wine
./GoogleChromePortable.exe >>log.txt 2>&1
...
0050: get_suspend_context( )
0050: get_suspend_context() = 0 {
context={cpu=x86,eip=f7772430,esp=0033ff14,ebp=0033ffe8,eflags=00000296,cs=0023,ss=002b,ds=002b,es=002b,fs=0063,gs=006b,eax=00000000,ebx=00000001,ecx=7bced260,edx=00000000,esi=00000008,edi=7bcd1000,dr0=00000000,dr1=00000000,dr2=00000000,dr3=00000000,dr6=00000000,dr7=00000000,fp.ctrl=ffff027f,fp.status=ffff0000,fp.tag=ffffffff,fp.err_off=00000000,fp.err_sel=00000023,fp.data_off=00000000,fp.data_sel=ffff002b,fp.cr0npx=00000000,fp.reg0=0,fp.reg1=0,fp.reg2=0,fp.reg3=0,fp.reg4=0,fp.reg5=0,fp.reg6=0,fp.reg7=0,extended={...}}
}
0050:trace:module:process_attach (L"chrome.exe",0x1) - START
0050:trace:module:process_attach (L"chrome_elf.dll",0x1) - START
0050:trace:module:process_attach (L"KERNEL32.dll",0x1) - START
0050:trace:module:process_attach (L"ntdll.dll",0x1) - START
0050:trace:module:MODULE_InitDLL (0x7bc10000 L"ntdll.dll",PROCESS_ATTACH,0x1) -
CALL
0050:trace:module:MODULE_InitDLL (0x7bc10000,PROCESS_ATTACH,0x1) - RETURN 1
0050:trace:module:process_attach (L"ntdll.dll",0x1) - END
0050:trace:module:MODULE_InitDLL (0x7b810000
L"KERNEL32.dll",PROCESS_ATTACH,0x1) - CALL
0050:trace:seh:raise_exception code=c0000005 flags=0 addr=0xfc365f ip=00fc365f
tid=0050
0050:trace:seh:raise_exception  info[0]=00000001
0050:trace:seh:raise_exception  info[1]=00000000
0050:trace:seh:raise_exception  eax=00000000 ebx=7bcd1000 ecx=0033f954
edx=0046a15c esi=0033fa30 edi=00000000
0050:trace:seh:raise_exception  ebp=0033f948 esp=0033f940 cs=0023 ds=002b
es=002b fs=0063 gs=006b flags=00010206
0050:trace:seh:call_stack_handlers calling handler at 0x7bc9de50 code=c0000005
flags=0
0050:trace:seh:__regs_RtlUnwind code=c0000005 flags=2
0050:trace:seh:__regs_RtlUnwind calling handler at 0x7bc81835 code=c0000005
flags=2
0050:trace:seh:__regs_RtlUnwind handler at 0x7bc81835 returned 1
0050:trace:module:MODULE_InitDLL (0x7b810000,PROCESS_ATTACH,0x1) - RETURN 0
0050:trace:module:MODULE_InitDLL (0x7b810000
L"KERNEL32.dll",PROCESS_DETACH,0x1) - CALL
0050:trace:module:MODULE_InitDLL (0x7b810000,PROCESS_DETACH,0x1) - RETURN 1
0050:warn:module:process_attach Initialization of L"KERNEL32.dll" failed
0050:trace:module:process_attach (L"KERNEL32.dll",0x1) - END
0050:trace:module:process_attach (L"chrome_elf.dll",0x1) - END
0050:trace:module:process_attach (L"chrome.exe",0x1) - END
0050:err:module:attach_process_dlls "KERNEL32.dll" failed to initialize,
aborting
0050:err:module:LdrInitializeThunk Main exe initialization for
L"Z:\\home\\focht\\Downloads\\GoogleChromePortable\\App\\Chrome-bin\\chrome.exe"
failed, status c0000005
--- snip ---

Exception address is 0xfc365f in client address space (render sandbox).

Parent process injecting code for the hooker thunk and API entry:

--- snip ---
...
0030: write_process_memory( handle=0364, addr=00fc3650,
data={8d,4c,24,04,83,e4,f0,ff,71,fc,55,89,e5,53,51,83,6c,00,00,00,00,00,00,00,83,ec,08,52,8b,54,24,0c,89,54,24,08,c7,44,24,0c,50,36,fc,00,c7,44,24,04,1b,0e,44,00,5a,c3}
)
0030: write_process_memory() = 0
...
0030: read_process_memory( handle=0364, addr=7bc5be28 )
0030: read_process_memory() = 0 {
data={8d,4c,24,04,83,e4,f0,ff,71,fc,55,89,e5,53,51,83} } 
...
0030: write_process_memory( handle=0364, addr=7bc5be28,
data={b8,4c,24,04,83,ba,68,36,fc,00,ff,e2} )
0050: *signal* signal=19
0030: write_process_memory() = 0 
--- snip ---

Original 'NtOpenThreadToken' API entry:

--- snip ---
$ ==>    7BC5BE28    8D4C24 04            LEA ECX,DWORD PTR SS:[ESP+4]
$+4      7BC5BE2C    83E4 F0              AND ESP,FFFFFFF0
$+7      7BC5BE2F    FF71 FC              PUSH DWORD PTR DS:[ECX-4]
$+A      7BC5BE32    55                   PUSH EBP
$+B      7BC5BE33    89E5                 MOV EBP,ESP
$+D      7BC5BE35    53                   PUSH EBX
$+E      7BC5BE36    51                   PUSH ECX
$+F      7BC5BE37    83EC 20              SUB ESP,20
$+12     7BC5BE3A    E8 D12CFCFF          CALL ntdll.__x86.get_pc_thunk.bx
$+17     7BC5BE3F    81C3 C1510700        ADD EBX,751C1
$+1D     7BC5BE45    89C8                 MOV EAX,ECX
$+1F     7BC5BE47    8B50 08              MOV EDX,DWORD PTR DS:[EAX+8]
$+22     7BC5BE4A    8855 F4              MOV BYTE PTR SS:[EBP-C],DL
$+25     7BC5BE4D    0FB655 F4            MOVZX EDX,BYTE PTR SS:[EBP-C]
$+29     7BC5BE51    8B48 0C              MOV ECX,DWORD PTR DS:[EAX+C]
$+2C     7BC5BE54    894C24 10            MOV DWORD PTR SS:[ESP+10],ECX
$+30     7BC5BE58    C74424 0C 00000000   MOV DWORD PTR SS:[ESP+C],0
$+38     7BC5BE60    895424 08            MOV DWORD PTR SS:[ESP+8],EDX
$+3C     7BC5BE64    8B50 04              MOV EDX,DWORD PTR DS:[EAX+4]
$+3F     7BC5BE67    895424 04            MOV DWORD PTR SS:[ESP+4],EDX
$+43     7BC5BE6B    8B00                 MOV EAX,DWORD PTR DS:[EAX]
$+45     7BC5BE6D    890424               MOV DWORD PTR SS:[ESP],EAX
$+48     7BC5BE70    E8 0F000000          CALL ntdll.NtOpenThreadTokenEx
$+4D     7BC5BE75    83EC 14              SUB ESP,14
$+50     7BC5BE78    8D65 F8              LEA ESP,DWORD PTR SS:[EBP-8]
$+53     7BC5BE7B    59                   POP ECX
$+54     7BC5BE7C    5B                   POP EBX
$+55     7BC5BE7D    5D                   POP EBP
$+56     7BC5BE7E    8D61 FC              LEA ESP,DWORD PTR DS:[ECX-4]
$+59     7BC5BE81    C2 1000              RETN 10 
--- snip ---

(1) API entry after hook patch:

--- snip ---
$        7BC5BE28    B8 4C240483          MOV EAX,8304244C
$+5      7BC5BE2D    BA 682E8500          MOV EDX,852E68
$+A      7BC5BE32    FFE2                 JMP EDX
...
--- snip ---

(2) Internal thunk (trampoline) to final hooker code:

--- snip ---
$+18     00196080    83EC 08              SUB ESP,8
$+1B     00196083    52                   PUSH EDX
$+1C     00196084    8B5424 0C            MOV EDX,DWORD PTR SS:[ESP+C]
$+20     00196088    895424 08            MOV DWORD PTR SS:[ESP+8],EDX
$+24     0019608C    C74424 0C 502E8500   MOV DWORD PTR SS:[ESP+C],852E50
$+2C     00196094    C74424 04 1B0E4400   MOV DWORD PTR SS:[ESP+4],440E1B
$+34     0019609C    5A                   POP EDX
$+35     0019609D    C3                   RETN
--- snip ---

(3) Hooker code:

--- snip ---
0x00440e1b: pushl    %ebp
0x00440e1c: movl    %esp,%ebp
0x00440e1e: call    0x0042e5f4
0x00440e23: movl    %eax,%ecx
0x00440e25: movl    0x0(%eax),%edx
0x00440e27: call    *0x8(%edx)
0x00440e2a: movl    %eax,%ecx
0x00440e2c: call    0x00430c42
0x00440e31: pushl    0x18(%ebp) 
...
--- snip ---

(4) Copy of original API entry code in client address space (sandbox):

--- snip ---
$ ==>    00196068    8D4C24 04            LEA ECX,DWORD PTR SS:[ESP+4]
$+4      0019606C    83E4 F0              AND ESP,FFFFFFF0
$+7      0019606F    FF71 FC              PUSH DWORD PTR DS:[ECX-4]
$+A      00196072    55                   PUSH EBP
$+B      00196073    89E5                 MOV EBP,ESP
$+D      00196075    53                   PUSH EBX
$+E      00196076    51                   PUSH ECX
$+F      00196077    8373 00 65           XOR DWORD PTR DS:[EBX],65 ; *boom*
$+13     0019607B    0072 00              ADD BYTE PTR DS:[EDX],DH
$+16     0019607E    73 00                JNB SHORT 00196080
--- snip ---

The parent process hook engine copies up to 16 bytes from the native API entry
to a client process "save" area which is later used as continuation after the
hook code is done.

NT-style usermode syscall entries have fixed architecture-specific layout which
doesn't exceed 16 bytes.
The crash is caused by the fact that Wine's native API implementation is
"normal" code and the hooker copying just stops short in the middle of opcode
sequence.

Resolving 'WONTFIX'.

Since a native client exists for Linux there is no real loss here.

As a matter of fact Opera uses exactly the same hooking scheme for their
sandbox, see bug 33698 (Opera switched to Chrome code base).

Regards

-- 
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.



More information about the wine-bugs mailing list