Skip to content

[TME] Compound index in tyre characteristics can easily be out of bounds #31

@kimden

Description

@kimden

Description

This line (min-life-turning) causes a problem, having 9 numbers instead of 10.

        <tyres max-life-turning="750 750 1500 3200 3200 1000 1000 1000 1000 1000"
               max-life-traction="1600 1600 3200 4320 5280 1000 1000 1000 1000 1000"
               min-life-turning="150 150 300 640 640 100 100 100 100"
               min-life-traction="800 800 1600 2400 2400 100 100 100 100 100"
               default-color="1 1 12 63 63 -1 -1 -1 -1 29"
               regular-transfer-turning="0.4 0.4 0.2 0.1 0.1 0 0 0 0 0"

However, even if it is fixed, the compounds 11+ are going to crash if allowed inside code. Spinner picking compound allows such numbers as 999 without telling they are taken modulo 10 or something like that.

Please make sure that nonexistent compounds are not choosable, the interface is clear, and the crashes don't happen (including some testing with sanitizers before releases).

Steps to reproduce

Start a game with compound with number at least 10 (at least 11 after kart_characteristics.xml is fixed)

If you happen to use asan or you were lucky, you will crash.

Configuration

commit 87d3c4f (Fri Jul 18 09:06:28 2025 +0200, Fix compilation error for certain aggressive players)
commit 0a1401d (Fri Aug 1 16:46:46 2025 +0200, Add filter GP output command to feed into the scoring helper) - latest git

Error message

bt from manjaro coredump (not mine)
#0  0x00007fa4d3daf74c in ?? () from /usr/lib/libc.so.6
#1  0x00007fa4d3d55dc0 in raise () from /usr/lib/libc.so.6
#2  0x00007fa4d3d3d57a in abort () from /usr/lib/libc.so.6
#3  0x00007fa4d409a421 in std::__glibcxx_assert_fail (file=<optimized out>, line=<optimized out>, function=<optimized out>, condition=<optimized out>) at /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++11/assert_fail.cc:41
#4  0x000055d9eda8ca3e in std::vector<float, std::allocator<float> >::operator[] (this=0x7ffd4c43d570, __n=9) at /usr/include/c++/15.1.1/bits/stl_vector.h:1263
#5  0x000055d9ede04acb in Tyres::reset (this=0x55da2cd2b260) at /tyre/src/karts/tyres_boilerplate.txt:17
#6  0x000055d9edda7f44 in Kart::reset (this=0x55da2b9a64f0) at /tyre/src/karts/kart.cpp:638
#7  0x000055d9ede757cf in World::reset (this=0x55da2b7a8490, restart=false) at /tyre/src/modes/world.cpp:371
#8  0x000055d9ede83ce8 in WorldWithRank::reset (this=0x55da2b7a8490, restart=false) at /tyre/src/modes/world_with_rank.cpp:71
#9  0x000055d9ede46715 in LinearWorld::reset (this=0x55da2b7a8490, restart=false) at /tyre/src/modes/linear_world.cpp:114
#10 0x000055d9ee064b3a in RaceManager::startNextRace (this=0x55da1a9764a0) at /tyre/src/race/race_manager.cpp:806
#11 0x000055d9ee063ca3 in RaceManager::startNew (this=0x55da1a9764a0, from_overworld=false) at /tyre/src/race/race_manager.cpp:609
#12 0x000055d9ee066a96 in RaceManager::startSingleRace (this=0x55da1a9764a0, track_ident="inuksuk--alpine-", num_laps=3, from_overworld=false) at /tyre/src/race/race_manager.cpp:1301
#13 0x000055d9ee214321 in TrackInfoScreen::onEnterPressedInternal (this=0x55da2b09d550) at /tyre/src/states_screens/track_info_screen.cpp:719
#14 0x000055d9ee2144de in TrackInfoScreen::eventCallback (this=0x55da2b09d550, widget=0x55da2bbb8d70, name="buttons", playerID=0) at /tyre/src/states_screens/track_info_screen.cpp:731
#15 0x000055d9edc39ad4 in GUIEngine::EventHandler::sendEventToUser (this=0x55da1a9a0660, widget=0x55da2bbb8d70, name="buttons", playerID=0) at /tyre/src/guiengine/event_handler.cpp:722
#16 0x000055d9edc39df2 in GUIEngine::EventHandler::onWidgetActivated (this=0x55da1a9a0660, w=0x55da2bbb9b00, playerID=0, type=Input::IT_MOUSEBUTTON) at /tyre/src/guiengine/event_handler.cpp:779
#17 0x000055d9edc3a16e in GUIEngine::EventHandler::onGUIEvent (this=0x55da1a9a0660, event=...) at /tyre/src/guiengine/event_handler.cpp:830
#18 0x000055d9edc3859a in GUIEngine::EventHandler::OnEvent (this=0x55da1a9a0660, event=...) at /tyre/src/guiengine/event_handler.cpp:163
#19 0x000055d9ee477c7b in irr::gui::CGUIEnvironment::OnEvent (this=0x55da184ea320, event=...) at /tyre/lib/irrlicht/source/Irrlicht/CGUIEnvironment.cpp:373
#20 0x000055d9ee3bea2d in irr::gui::CGUIButton::OnEvent (this=0x55da2b7e76a0, event=...) at /tyre/lib/irrlicht/source/Irrlicht/CGUIButton.cpp:228
#21 0x000055d9ee3be9dd in irr::gui::CGUIButton::OnEvent (this=0x55da2b7bcf60, event=...) at /tyre/lib/irrlicht/source/Irrlicht/CGUIButton.cpp:218
#22 0x000055d9ee47890b in irr::gui::CGUIEnvironment::postEventFromUser (this=0x55da184ea320, event=...) at /tyre/lib/irrlicht/source/Irrlicht/CGUIEnvironment.cpp:544
#23 0x000055d9ee3cf6b4 in irr::CIrrDeviceStub::postEventFromUser (this=0x55da176db9f0, event=...) at /tyre/lib/irrlicht/source/Irrlicht/CIrrDeviceStub.cpp:227
#24 0x000055d9ee3c4b36 in irr::CIrrDeviceSDL::run (this=0x55da176db9f0) at /tyre/lib/irrlicht/source/Irrlicht/CIrrDeviceSDL.cpp:936
#25 0x000055d9ede2b4dd in MainLoop::run (this=0x55da1b064fe0) at /tyre/src/main_loop.cpp:705
#26 0x000055d9ede236e7 in main (argc=1, argv=0x7ffd4c43e6b8) at /tyre/src/main.cpp:2634
asan from ubuntu (mine)
=================================================================
==86801==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x604000c987b4 at pc 0x5edb2f07904b bp 0x7ffd80503a80 sp 0x7ffd80503a70
READ of size 4 at 0x604000c987b4 thread T0
    #0 0x5edb2f07904a in Tyres::reset() /tyre/src/karts/tyres_boilerplate.txt:17
    #1 0x5edb2efa5e41 in Kart::reset() /tyre/src/karts/kart.cpp:638
    #2 0x5edb2f173986 in World::reset(bool) /tyre/src/modes/world.cpp:371
    #3 0x5edb2f192973 in WorldWithRank::reset(bool) /tyre/src/modes/world_with_rank.cpp:71
    #4 0x5edb2f1071a8 in LinearWorld::reset(bool) /tyre/src/modes/linear_world.cpp:114
    #5 0x5edb2f5bb464 in RaceManager::startNextRace() /tyre/src/race/race_manager.cpp:806
    #6 0x5edb2f5b98a6 in RaceManager::startNew(bool) /tyre/src/race/race_manager.cpp:609
    #7 0x5edb2f5bf7f9 in RaceManager::startSingleRace(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, bool) /tyre/src/race/race_manager.cpp:1301
    #8 0x5edb2f999601 in TrackInfoScreen::onEnterPressedInternal() /tyre/src/states_screens/track_info_screen.cpp:719
    #9 0x5edb2f9999a3 in TrackInfoScreen::eventCallback(GUIEngine::Widget*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int) /tyre/src/states_screens/track_info_screen.cpp:731
    #10 0x5edb2ec4b5de in GUIEngine::EventHandler::sendEventToUser(GUIEngine::Widget*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, int) /tyre/src/guiengine/event_handler.cpp:722
    #11 0x5edb2ec4be99 in GUIEngine::EventHandler::onWidgetActivated(GUIEngine::Widget*, int, Input::InputType) /tyre/src/guiengine/event_handler.cpp:779
    #12 0x5edb2ec4c5c4 in GUIEngine::EventHandler::onGUIEvent(irr::SEvent const&) /tyre/src/guiengine/event_handler.cpp:830
    #13 0x5edb2ec4807f in GUIEngine::EventHandler::OnEvent(irr::SEvent const&) /tyre/src/guiengine/event_handler.cpp:163
    #14 0x5edb2ff88652 in irr::gui::CGUIEnvironment::OnEvent(irr::SEvent const&) /tyre/lib/irrlicht/source/Irrlicht/CGUIEnvironment.cpp:373
    #15 0x5edb2fda28c6 in irr::gui::CGUIButton::OnEvent(irr::SEvent const&) /tyre/lib/irrlicht/source/Irrlicht/CGUIButton.cpp:228
    #16 0x5edb2fda280b in irr::gui::CGUIButton::OnEvent(irr::SEvent const&) /tyre/lib/irrlicht/source/Irrlicht/CGUIButton.cpp:218
    #17 0x5edb2ff8af1e in irr::gui::CGUIEnvironment::postEventFromUser(irr::SEvent const&) /tyre/lib/irrlicht/source/Irrlicht/CGUIEnvironment.cpp:544
    #18 0x5edb2fdd189f in irr::CIrrDeviceStub::postEventFromUser(irr::SEvent const&) /tyre/lib/irrlicht/source/Irrlicht/CIrrDeviceStub.cpp:227
    #19 0x5edb2fdb2cbd in irr::CIrrDeviceSDL::run() /tyre/lib/irrlicht/source/Irrlicht/CIrrDeviceSDL.cpp:936
    #20 0x5edb2f0ca2fc in MainLoop::run() /tyre/src/main_loop.cpp:705
    #21 0x5edb2f0bb39b in main /tyre/src/main.cpp:2634
    #22 0x7dc08a82814f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #23 0x7dc08a828208 in __libc_start_main_impl ../csu/libc-start.c:360
    #24 0x5edb2e6b9b14 in _start (/tyre/build_d/bin/supertuxkart+0xfefb14) (BuildId: 71bd0d058449fe4bbea0b76cc0f621305d6603d4)

0x604000c987b4 is located 0 bytes after 36-byte region [0x604000c98790,0x604000c987b4)
allocated by thread T0 here:
    #0 0x7dc08c6dfba8 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x5edb2e88087b in std::__new_allocator<float>::allocate(unsigned long, void const*) /usr/include/c++/13/bits/new_allocator.h:147
    #2 0x5edb2e879f92 in std::allocator_traits<std::allocator<float> >::allocate(std::allocator<float>&, unsigned long) /usr/include/c++/13/bits/alloc_traits.h:482
    #3 0x5edb2e879f92 in std::_Vector_base<float, std::allocator<float> >::_M_allocate(unsigned long) /usr/include/c++/13/bits/stl_vector.h:378
    #4 0x5edb2e874b98 in float* std::vector<float, std::allocator<float> >::_M_allocate_and_copy<__gnu_cxx::__normal_iterator<float const*, std::vector<float, std::allocator<float> > > >(unsigned long, __gnu_cxx::__normal_iterator<float const*, std::vector<float, std::allocator<float> > >, __gnu_cxx::__normal_iterator<float const*, std::vector<float, std::allocator<float> > >) /usr/include/c++/13/bits/stl_vector.h:1616
    #5 0x5edb2e87174e in std::vector<float, std::allocator<float> >::operator=(std::vector<float, std::allocator<float> > const&) /usr/include/c++/13/bits/vector.tcc:238
    #6 0x5edb2ef085f3 in CachedCharacteristic::process(AbstractCharacteristic::CharacteristicType, AbstractCharacteristic::Value, bool*) const /tyre/src/karts/cached_characteristic.cpp:191
    #7 0x5edb2eef0d3c in AbstractCharacteristic::getTyresMinLifeTurning() const /tyre/src/karts/abstract_characteristic.cpp:1515
    #8 0x5edb2f0213b6 in KartProperties::getTyresMinLifeTurning() const /tyre/src/karts/kart_properties.cpp:1175
    #9 0x5edb2f078fac in Tyres::reset() /tyre/src/karts/tyres_boilerplate.txt:17
    #10 0x5edb2efa5e41 in Kart::reset() /tyre/src/karts/kart.cpp:638
    #11 0x5edb2f173986 in World::reset(bool) /tyre/src/modes/world.cpp:371
    #12 0x5edb2f192973 in WorldWithRank::reset(bool) /tyre/src/modes/world_with_rank.cpp:71
    #13 0x5edb2f1071a8 in LinearWorld::reset(bool) /tyre/src/modes/linear_world.cpp:114
    #14 0x5edb2f5bb464 in RaceManager::startNextRace() /tyre/src/race/race_manager.cpp:806
    #15 0x5edb2f5b98a6 in RaceManager::startNew(bool) /tyre/src/race/race_manager.cpp:609
    #16 0x5edb2f5bf7f9 in RaceManager::startSingleRace(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, bool) /tyre/src/race/race_manager.cpp:1301
    #17 0x5edb2f999601 in TrackInfoScreen::onEnterPressedInternal() /tyre/src/states_screens/track_info_screen.cpp:719
    #18 0x5edb2f9999a3 in TrackInfoScreen::eventCallback(GUIEngine::Widget*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int) /tyre/src/states_screens/track_info_screen.cpp:731
    #19 0x5edb2ec4b5de in GUIEngine::EventHandler::sendEventToUser(GUIEngine::Widget*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, int) /tyre/src/guiengine/event_handler.cpp:722
    #20 0x5edb2ec4be99 in GUIEngine::EventHandler::onWidgetActivated(GUIEngine::Widget*, int, Input::InputType) /tyre/src/guiengine/event_handler.cpp:779
    #21 0x5edb2ec4c5c4 in GUIEngine::EventHandler::onGUIEvent(irr::SEvent const&) /tyre/src/guiengine/event_handler.cpp:830
    #22 0x5edb2ec4807f in GUIEngine::EventHandler::OnEvent(irr::SEvent const&) /tyre/src/guiengine/event_handler.cpp:163
    #23 0x5edb2ff88652 in irr::gui::CGUIEnvironment::OnEvent(irr::SEvent const&) /tyre/lib/irrlicht/source/Irrlicht/CGUIEnvironment.cpp:373
    #24 0x5edb2fda28c6 in irr::gui::CGUIButton::OnEvent(irr::SEvent const&) /tyre/lib/irrlicht/source/Irrlicht/CGUIButton.cpp:228
    #25 0x5edb2fda280b in irr::gui::CGUIButton::OnEvent(irr::SEvent const&) /tyre/lib/irrlicht/source/Irrlicht/CGUIButton.cpp:218
    #26 0x5edb2ff8af1e in irr::gui::CGUIEnvironment::postEventFromUser(irr::SEvent const&) /tyre/lib/irrlicht/source/Irrlicht/CGUIEnvironment.cpp:544
    #27 0x5edb2fdd189f in irr::CIrrDeviceStub::postEventFromUser(irr::SEvent const&) /tyre/lib/irrlicht/source/Irrlicht/CIrrDeviceStub.cpp:227
    #28 0x5edb2fdb2cbd in irr::CIrrDeviceSDL::run() /tyre/lib/irrlicht/source/Irrlicht/CIrrDeviceSDL.cpp:936
    #29 0x5edb2f0ca2fc in MainLoop::run() /tyre/src/main_loop.cpp:705
    #30 0x5edb2f0bb39b in main /tyre/src/main.cpp:2634

SUMMARY: AddressSanitizer: heap-buffer-overflow /tyre/src/karts/tyres_boilerplate.txt:17 in Tyres::reset()
Shadow bytes around the buggy address:
  0x604000c98500: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fa
  0x604000c98580: fa fa fd fd fd fd fd fa fa fa fa fa fa fa fa fa
  0x604000c98600: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fa
  0x604000c98680: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fa
  0x604000c98700: fa fa fa fa fa fa fa fa fa fa fd fd fd fd fd fa
=>0x604000c98780: fa fa 00 00 00 00[04]fa fa fa fa fa fa fa fa fa
  0x604000c98800: fa fa 00 00 00 00 00 fa fa fa fd fd fd fd fd fa
  0x604000c98880: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fa
  0x604000c98900: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fd
  0x604000c98980: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fd
  0x604000c98a00: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==86801==ABORTING

Log File (stdout.log)

Input Configuration (input.xml)

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingenhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions