contrib: add symbol-check test for non-existence of vmova instructions in Windows build #28413

issue fanquake openend this issue on September 5, 2023
  1. fanquake commented at 12:35 pm on September 5, 2023: member

    Given we are patching the Windows GCC used for releases, to avoid the use of certain aligned assembly instructions, we should probably add a symbol-check test to ensure the patches are working as intended.

    See #24726, #24736 and #28151 for the background here.

  2. fanquake added the label Windows on Sep 5, 2023
  3. laanwj commented at 10:32 am on April 11, 2024: member

    Wouldn’t checking the instructions be more of a security-check instead of a symbol-check?

    Assigning myself as I’m interested on working on this.

  4. laanwj assigned laanwj on Apr 11, 2024
  5. laanwj commented at 8:53 pm on April 14, 2024: member
    Is introducing a dependency on the python capstone binding acceptable here? It’s not possible to do this check without a disassembler of some kind, we don’t want to rely on calling out to objdump, and i’m not sure we want our own x86 mini-disassembler (hard to review, slow in pure python). Capstone is great for this and might help in future instruction security checks as well. But it’s another build-time dep.
  6. laanwj commented at 3:51 am on April 15, 2024: member

    For reference, with capstone this check is as simple as:

     0# Intel® 64 and IA-32 Architectures Software Developer’s Manual:
     1#   chapter 14.9, table 14-22. Instructions Requiring Explicitly Aligned Memory
     2#   chapter 15.7, Table 15-6. SIMD Instructions Requiring Explicitly Aligned Memory
     3#
     4# This amounts to the following instructions:
     5#
     6# instruction                  chapter 4.3 section
     7# ---------------------------  ---------------------------------
     8# (V)MOVDQA xmm, mBBB          MOVDQA,VMOVDQA32/64—Move Aligned Packed Integer Values
     9# (V)MOVDQA mBBB, xmm          MOVDQA,VMOVDQA32/64—Move Aligned Packed Integer Values
    10# (V)MOVAPS xmm, mBBB          MOVAPS—Move Aligned Packed Single Precision Floating-Point Values
    11# (V)MOVAPS mBBB, xmm          MOVAPS—Move Aligned Packed Single Precision Floating-Point Values
    12# (V)MOVAPD xmm, mBBB          MOVAPD—Move Aligned Packed Double Precision Floating-Point Values
    13# (V)MOVAPD mBBB, xmm          MOVAPD—Move Aligned Packed Double Precision Floating-Point Values
    14# (V)MOVNTPS mBBB, xmm         MOVNTPS—Store Packed Single Precision Floating-Point Values Using Non-Temporal Hint
    15# (V)MOVNTPD mBBB, xmm         MOVNTPD—Store Packed Double Precision Floating-Point Values Using Non-Temporal Hint
    16# (V)MOVNTDQ mBBB, xmm         MOVNTDQ—Store Packed Integers Using Non-Temporal Hint
    17# (V)MOVNTDQA xmm, mBBB        MOVNTDQA—Load Double Quadword Non-Temporal Aligned Hint
    18#
    19# BBB is the bit size, which can be 128, 256 or 512.
    20#
    21FORBIDDEN_VMOVA = {
    22    capstone.x86.X86_INS_MOVDQA,    capstone.x86.X86_INS_VMOVDQA,   capstone.x86.X86_INS_VMOVDQA32, capstone.x86.X86_INS_VMOVDQA64,
    23    capstone.x86.X86_INS_MOVAPS,    capstone.x86.X86_INS_VMOVAPS,
    24    capstone.x86.X86_INS_MOVAPD,    capstone.x86.X86_INS_VMOVAPD,
    25    capstone.x86.X86_INS_MOVNTPS,   capstone.x86.X86_INS_VMOVNTPS,
    26    capstone.x86.X86_INS_MOVNTPD,   capstone.x86.X86_INS_VMOVNTPD,
    27    capstone.x86.X86_INS_MOVNTDQ,   capstone.x86.X86_INS_VMOVNTDQ,
    28    capstone.x86.X86_INS_MOVNTDQA,  capstone.x86.X86_INS_VMOVNTDQA,
    29}
    30
    31def check_ELF_no_vmova(binary) -> bool:
    32    '''
    33    Check for vmov instructions that require alignment.
    34    These are a potential problem due to a stack alignment bug in GCC on Windows.
    35    See [#28413](/bitcoin-bitcoin/28413/) for specifics.
    36    '''
    37    cs = capstone.Cs(capstone.CS_ARCH_X86, capstone.CS_MODE_64)
    38
    39    found_forbidden = False
    40    for segment in binary.segments:
    41        # Find loaded, executable segments
    42        if segment.type == lief.ELF.SEGMENT_TYPES.LOAD and (segment.flags & lief.ELF.SEGMENT_FLAGS.X) != 0:
    43            # disassemble segment, check every instruction
    44            for i in cs.disasm(segment.content, segment.virtual_address): # -> CsInsn
    45                if i.id in FORBIDDEN_VMOVA:
    46                    found_forbidden = True
    47
    48    return not found_forbidden
    

    Still need to port this to PE.

    And figure out what the exceptions are in the current release, and how to either get rid of them, or identify them.


fanquake laanwj

Labels
Windows


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-12-21 15:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me