Skip to content

Undefined behavior in ZydisGetOperandSizeFromElementSize (memory alignment) #523

@wareya

Description

@wareya

I'm using Zydis as an instruction encoder. I'm using the amalgamated version. When I compile my application with ubsan (i.e. clang and -fsanitize=undefined) I get a memory-alignment-related UB error:

src/x86/../../thirdparty/zydis/Zydis.c:15653:24: runtime error: load of misaligned address 0x55d8e70361db for type 'const ZyanU16 *' (aka 'const unsigned short *'), which requires 2 byte alignment
0x55d8e70361db: note: pointer points here

(Line number differs because of unrelated changes I had to make to get it to compile as both C and C++)

The responsible call is the one that looks like:

                match->eosz = ZydisGetOperandSizeFromElementSize(match, def_op->size,
                    user_op->mem.size, ZYAN_TRUE);

I don't know why this is happening; I think it might have something to do with ZydisOperandDefinition having bitfields.

I don't know how to keep the array aligned to a multiple of 2, but doing this works:

static ZyanU8 ZydisGetOperandSizeFromElementSize(ZydisEncoderInstructionMatch *match,
    const ZyanU16 *_size_table, ZyanU16 desired_size, ZyanBool exact_match_mode)
{
    ZyanU16 size_table[3];
    ZYAN_MEMCPY(size_table, (void*)_size_table, sizeof(ZyanU16) * 3);
    // ...

For some reason the explicit (void*) cast is necessary to keep ubsan from complaining.

(This is all while compiling as C, like intended)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-decoderArea: DecoderC-bugCategory: This is a bug (or a fix for a bug, when applied to PRs)P-mediumPriority: Medium

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions