alberthdev / spasm-ng

SPASM-ng is a z80 assembler with extra features to support development for TI calculators.
GNU General Public License v2.0
95 stars 24 forks source link

Uninitialized read in malformed eZ80 instruction #52

Open tari opened 6 years ago

tari commented 6 years ago

I think this causes unpredictable behavior in optimized emscripten builds, but it might be a false positive in the stdlib.

$ echo > tests/bugs/ez80-invalid-de-ld.asm << EOF
; Test handling of invalid opcode `ld (de), $0A`
; RUN-ARGS: -E
    ld de, $FC0000
    ld (de), $0A
    ret
EOF
$ make CC=clang++ CXXFLAGS="-DUNIXVER -DUSE_REUSABLES -DUSE_BUILTIN_FCREATE -fsanitize=memory -fsanitize=undefined" LDFLAGS="-lm -lgmp -lcrypto -fsanitize=memory -fsanitize-memory-track-origins -fsanitize=undefined" STRIP=echo
$ ./spasm -E ./tests/bugs/ez80-invalid-de-ld.asm
==21355==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x55e357aea0b2 in std::_Rb_tree<char const*, std::pair<char const* const, void*>, std::_Select1st<std::pair<char const* const, void*> >, comparator, std::allocator<std::pair<char const* const, void*> > >::_M_lower_bound(std::_Rb_tree_node<std::pair<char const* const, void*> >*, std::_Rb_tree_node_base*, char const* const&) (/caring/sync/tari/projects/spasm-ng/spasm+0x1750b2)
    #1 0x55e357afc3c7 in std::_Rb_tree<char const*, std::pair<char const* const, void*>, std::_Select1st<std::pair<char const* const, void*> >, comparator, std::allocator<std::pair<char const* const, void*> > >::find(char const* const&) (/caring/sync/tari/projects/spasm-ng/spasm+0x1873c7)
    #2 0x55e357adfa2e in std::map<char const*, void*, comparator, std::allocator<std::pair<char const* const, void*> > >::find(char const* const&) (/caring/sync/tari/projects/spasm-ng/spasm+0x16aa2e)
    #3 0x55e357adb7e7 in hash_lookup(hash_t*, char const*) (/caring/sync/tari/projects/spasm-ng/spasm+0x1667e7)
    #4 0x55e357b226b0 in search_defines(char const*, bool) (/caring/sync/tari/projects/spasm-ng/spasm+0x1ad6b0)
    #5 0x55e357b1de7e in add_define(char*, bool*, bool) (/caring/sync/tari/projects/spasm-ng/spasm+0x1a8e7e)
    #6 0x55e357b19b7c in init_storage() (/caring/sync/tari/projects/spasm-ng/spasm+0x1a4b7c)
    #7 0x55e357a4cc93 in main (/caring/sync/tari/projects/spasm-ng/spasm+0xd7c93)
    #8 0x7f72d66eff49 in __libc_start_main (/usr/lib/libc.so.6+0x20f49)
    #9 0x55e3579c4df9 in _start (/caring/sync/tari/projects/spasm-ng/spasm+0x4fdf9)

  Uninitialized value was stored to memory at
    #0 0x55e357aea766 in std::_Rb_tree<char const*, std::pair<char const* const, void*>, std::_Select1st<std::pair<char const* const, void*> >, comparator, std::allocator<std::pair<char const* const, void*> > >::_M_lower_bound(std::_Rb_tree_node<std::pair<char const* const, void*> >*, std::_Rb_tree_node_base*, char const* const&) (/caring/sync/tari/projects/spasm-ng/spasm+0x175766)
    #1 0x55e357afc3c7 in std::_Rb_tree<char const*, std::pair<char const* const, void*>, std::_Select1st<std::pair<char const* const, void*> >, comparator, std::allocator<std::pair<char const* const, void*> > >::find(char const* const&) (/caring/sync/tari/projects/spasm-ng/spasm+0x1873c7)
    #2 0x55e357adfa2e in std::map<char const*, void*, comparator, std::allocator<std::pair<char const* const, void*> > >::find(char const* const&) (/caring/sync/tari/projects/spasm-ng/spasm+0x16aa2e)
    #3 0x55e357adb7e7 in hash_lookup(hash_t*, char const*) (/caring/sync/tari/projects/spasm-ng/spasm+0x1667e7)
    #4 0x55e357b226b0 in search_defines(char const*, bool) (/caring/sync/tari/projects/spasm-ng/spasm+0x1ad6b0)
    #5 0x55e357b1de7e in add_define(char*, bool*, bool) (/caring/sync/tari/projects/spasm-ng/spasm+0x1a8e7e)
    #6 0x55e357b19b7c in init_storage() (/caring/sync/tari/projects/spasm-ng/spasm+0x1a4b7c)
    #7 0x55e357a4cc93 in main (/caring/sync/tari/projects/spasm-ng/spasm+0xd7c93)
    #8 0x7f72d66eff49 in __libc_start_main (/usr/lib/libc.so.6+0x20f49)

  Uninitialized value was created by a heap allocation
    #0 0x55e357a4313d in operator new(unsigned long) (/caring/sync/tari/projects/spasm-ng/spasm+0xce13d)
    #1 0x55e357af24f6 in __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<char const* const, void*> > >::allocate(unsigned long, void const*) (/caring/sync/tari/projects/spasm-ng/spasm+0x17d4f6)
    #2 0x55e357af1faf in std::allocator_traits<std::allocator<std::_Rb_tree_node<std::pair<char const* const, void*> > > >::allocate(std::allocator<std::_Rb_tree_node<std::pair<char const* const, void*> > >&, unsigned long) (/caring/sync/tari/projects/spasm-ng/spasm+0x17cfaf)
    #3 0x55e357af0f37 in std::_Rb_tree<char const*, std::pair<char const* const, void*>, std::_Select1st<std::pair<char const* const, void*> >, comparator, std::allocator<std::pair<char const* const, void*> > >::_M_get_node() (/caring/sync/tari/projects/spasm-ng/spasm+0x17bf37)
    #4 0x55e357aec3f5 in std::_Rb_tree_node<std::pair<char const* const, void*> >* std::_Rb_tree<char const*, std::pair<char const* const, void*>, std::_Select1st<std::pair<char const* const, void*> >, comparator, std::allocator<std::pair<char const* const, void*> > >::_M_create_node<std::piecewise_construct_t const&, std::tuple<char const*&&>, std::tuple<> >(std::piecewise_construct_t const&, std::tuple<char const*&&>&&, std::tuple<>&&) (/caring/sync/tari/projects/spasm-ng/spasm+0x1773f5)
    #5 0x55e357ae834c in std::_Rb_tree_iterator<std::pair<char const* const, void*> > std::_Rb_tree<char const*, std::pair<char const* const, void*>, std::_Select1st<std::pair<char const* const, void*> >, comparator, std::allocator<std::pair<char const* const, void*> > >::_M_emplace_hint_unique<std::piecewise_construct_t const&, std::tuple<char const*&&>, std::tuple<> >(std::_Rb_tree_const_iterator<std::pair<char const* const, void*> >, std::piecewise_construct_t const&, std::tuple<char const*&&>&&, std::tuple<>&&) (/caring/sync/tari/projects/spasm-ng/spasm+0x17334c)
    #6 0x55e357adf40b in std::map<char const*, void*, comparator, std::allocator<std::pair<char const* const, void*> > >::operator[](char const*&&) (/caring/sync/tari/projects/spasm-ng/spasm+0x16a40b)
    #7 0x55e357adb1f8 in hash_insert(hash_t*, void*) (/caring/sync/tari/projects/spasm-ng/spasm+0x1661f8)
    #8 0x55e357b1fad3 in add_define(char*, bool*, bool) (/caring/sync/tari/projects/spasm-ng/spasm+0x1aaad3)
    #9 0x55e357b1993b in init_storage() (/caring/sync/tari/projects/spasm-ng/spasm+0x1a493b)
    #10 0x55e357a4cc93 in main (/caring/sync/tari/projects/spasm-ng/spasm+0xd7c93)
    #11 0x7f72d66eff49 in __libc_start_main (/usr/lib/libc.so.6+0x20f49)

SUMMARY: MemorySanitizer: use-of-uninitialized-value (/caring/sync/tari/projects/spasm-ng/spasm+0x1750b2) in std::_Rb_tree<char const*, std::pair<char const* const, void*>, std::_Select1st<std::pair<char const* const, void*> >, comparator, std::allocator<std::pair<char const* const, void*> > >::_M_lower_bound(std::_Rb_tree_node<std::pair<char const* const, void*> >*, std::_Rb_tree_node_base*, char const* const&)
Exiting
alberthdev commented 6 years ago

Wouldn't be surprised if this was the case... we've ran a few coverity scans a while back and there were definitely issues that cropped up, some of which may overlap here...