Hyperscan crashes when built for 32-bit Windows
- Dominant language
- C++
- Stars
- 5.5k
- Forks
- 816
- Avg merge
- 4d 21h
- Merged PRs (30d)
- 2
Description
We've found that Hyperscan crashes reliably when built to target 32-bit Windows.
To reproduce:
* Build Hyperscan 5.3.0 targeting Windows 32-bit using VS2019.
* `cmake -G "Visual Studio 16 2019" -A Win32 -DBOOST_ROOT="%cd%\..\boost" -DCMAKE_INSTALL_PREFIX="%cd%\hyperscan-win-32" -DCMAKE_PROGRAM_PATH="%cd%\.." -DBUILD_STATIC_AND_SHARED=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo ..\hyperscan"`
* `devenv.com hyperscan.sln /Build RelWithDebInfo /Project ALL_BUILD.vcxproj /ProjectConfig RelWithDebInfo`
* `devenv.com hyperscan.sln /Build RelWithDebInfo /Project INSTALL.vcxproj /ProjectConfig RelWithDebInfo`
* Compile the `examples\simplegrep.c` example program targeting 32-bit Windows and link it against the 32-bit Hyperscan DLL.
* The `cmake` configuration shipped with the Hyperscan source release is meant to compile `simplegrep` in Unix-like systems.
* To compile in 64-bit Windows targeting 32-bit, start the VS command file to set up the environment:
`"\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvarsamd64_x86.bat"`
* Then compile `simplegrep`:
```
cl simplegrep.c /I hyperscan-win-32\include /link hs.lib /libpath:hyperscan-win-32\lib
```
* Run `simplegrep.exe` and observe it crash.
* Many patterns cause a crash, some times after some delay. This pattern causes it to crash reliability on a large enough input.
* This pattern may trigger Windows Defender. You may need to disable it or configure it to allow the program to run if it shows a warning.
* To reproduce the crash execute:
```
simplegrep "(crypto::(capi|certificates|scauth|cng|keys|stores|providers|sc)|dpapi::(capi|wwan|blob|cng|wifi|cache|chrome|cred|vault|credhist|masterkey|protect)|kerberos::(silver|ptt|tgt|golden|purge|list)|lsadump::(trust|dcsync|dcshadow|sam|rpdata|cache|lsa|netsync|secrets|backupkeys)|sekurlsa::(logonpasswords|process|credman|wdigest|ssp|kerberos|livessp|tickets|dpapi|msv|searchpasswords|tspkg|pth|ekeys|minidump)|token::(list|whoami|revert|elevate)|vault::(list|cred)|privilege::debug|ts::multirdp)" hyperscan-win-32\include\hs_common.h
```
The return code is
```
echo %errorlevel%
-1073741819
```
In the the Event View, Windows Logs, Application, you'll see an event like:
```
Exception thrown at 0x51A8EDCB (hs.dll) in simplegrep.exe: 0xC0000005: Access violation reading location 0xA4DC6A68.
```
The call stack when the crash occurs is:
* `fdr_engine_exec`
* `fdrExec` in `fdr.c`
* `hwlmExec` in `hwlm.c`
* `pureLiteralBlockExec` (inline) in `runtime.c`
* `hs_scan` in `runtime.c`
In `fd_engine_exec` case 4 is taken, which has code generated by the macro call `FDR_MAIN_LOOP(z, state, get_conf_stride_4)`. This macro generates code that calls a number of functions that are inlined. Some of those make use of intrinsic instructions
The access violation appear to occur in `load_m128_from_u64a`, in `hs.dll`, and defined in `simd_utils.h`, when it calls the `_mm_set_epi64x` intrinsic, which tries to access an invalid address . `load_m128_from_u64a` is called from `get_conf_stride_4`, the second instance of a call (`load_m128_from_u64a(ft + reach4)`)
The same occurs if we use the 32-bit toolchain to target 32-bit (i.e. using `vcvars32.bat` to set up the environment).
Contributor guide
Assessment
This issue has not been assessed yet.