Closed G33KatWork closed 3 years ago
@G33KatWork thanks for the issue! I'll take a look. The test case makes it a lot easier to debug.
I just compiled the PoC with thread-sanitization. At first the bug seemed to have vanished, but I then just ran the executable in an endless loop over and over again which yielded this: https://gist.github.com/G33KatWork/7e14d98fab99148262164e52fcb10e31
insn_regs_intel_sorted
indeed is a global variable in capstone itself which is only referenced by the function X86_insn_reg_intel
. So allocating it on the stack inside of that function if size allows for it or on a thread-safe heap (dumb question, but are usual libc heap allocators even thread-safe?) might fix it.
I just verified that this is indeed the bug. Executing test()
once in the main function before starting all the threads triggers the path that does the racy initialization and now the assertions hold all the time. Yay!
Per my comment on the upstream capstone issue, it appears this bug was fixed in the next
branch. https://github.com/aquynh/capstone/issues/1647#issuecomment-647044700
We may fix this bug by upgrade capstone-rs
's captive capstone version.
Hi!
I've been playing around with Capstone to test a custom assembler I'm writing right now. During a test I take my assembled instruction and let Capstone disassemble it. I then compare the returned operands to determine if my assembler did the correct thing or not.
The rust tests are executed in a multi-threaded environment and sometimes, I get wrong results. When I execute the test suite with just a single thread, the tests all work fine. If the results are wrong, there is always one operand missing.
My test instruction right now is a
xor eax, 0x80000000
. The decoded result after some conversion is supposed to be (ignore the Rax, instead of Eax, it's correct!):Instead, when it fails, I always get this:
I created a small test application for you. It won't fail all the time, but when I just ran it like 3 or 4 times, it failed at least once