So, I just discovered a buffer overrun in the do_cmd_fire() routine. I believe this was triggered by
1. Firing an arrow from my inventory, the last arrow of its type
2. Hitting "n" to fire again
3. Selecting a different variety of arrow
Not sure that's exactly what happened though. In any case the game promptly imploded:
Code: Select all
/home/proteus/Projects/tome2/src/cmd2.cc:3272:31: runtime error: index 17 out of bounds for type 'short int [10]'
/home/proteus/Projects/tome2/src/cmd2.cc:3272:31: runtime error: load of address 0x000001b9f5e2 with insufficient space for an object of type 's16b'
0x000001b9f5e2: note: pointer points here
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
^
=================================================================
==9270==ERROR: AddressSanitizer: global-buffer-overflow on address 0x000001b9f5e2 at pc 0x000000bbb818 bp 0x7ffc0da80280 sp 0x7ffc0da80278
READ of size 2 at 0x000001b9f5e2 thread T0
#0 0xbbb817 in do_cmd_fire() (/home/proteus/Projects/tome2/src/tome+0xbbb817)
#1 0x6eafaa in process_command() (/home/proteus/Projects/tome2/src/tome+0x6eafaa)
#2 0x6eec2d in process_player() (/home/proteus/Projects/tome2/src/tome+0x6eec2d)
#3 0x6f2ee4 in dungeon() (/home/proteus/Projects/tome2/src/tome+0x6f2ee4)
#4 0x6f6465 in play_game (/home/proteus/Projects/tome2/src/tome+0x6f6465)
#5 0x671beb in main (/home/proteus/Projects/tome2/src/tome+0x671beb)
#6 0x7f07a139686f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2086f)
#7 0x6632f8 in _start (/home/proteus/Projects/tome2/src/tome+0x6632f8)
0x000001b9f5e2 is located 14 bytes to the right of global variable 'ddx' defined in '/home/proteus/Projects/tome2/src/tables.cc:55:6' (0x1b9f5c0) of size 20
0x000001b9f5e2 is located 30 bytes to the left of global variable 'ddy' defined in '/home/proteus/Projects/tome2/src/tables.cc:58:6' (0x1b9f600) of size 20
SUMMARY: AddressSanitizer: global-buffer-overflow ??:0 do_cmd_fire()
Shadow bytes around the buggy address:
0x00008036be60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00008036be70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00008036be80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00008036be90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00008036bea0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x00008036beb0: 00 00 02 f9 f9 f9 f9 f9 00 00 04 f9[f9]f9 f9 f9
0x00008036bec0: 00 00 04 f9 f9 f9 f9 f9 00 00 02 f9 f9 f9 f9 f9
0x00008036bed0: 00 00 02 f9 f9 f9 f9 f9 00 00 f9 f9 f9 f9 f9 f9
0x00008036bee0: 00 00 00 00 06 f9 f9 f9 f9 f9 f9 f9 00 00 00 00
0x00008036bef0: 06 f9 f9 f9 f9 f9 f9 f9 00 00 00 00 06 f9 f9 f9
0x00008036bf00: f9 f9 f9 f9 00 00 00 00 06 f9 f9 f9 f9 f9 f9 f9
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
Heap right redzone: fb
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
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
==9270==ABORTING
I will see if I can reproduce this.
Edit: got it. My inventory looked like this:
Code: Select all
...
q) 13 Arrows of Wounding
r) A Seeker Arrow of Slay Evil
(end of inventory)
...
I hit 'f r' and a direction to fire the Seeker Arrow.
Then I hit 'n' to fire again. Item slot (r) is now empty.
The game prompts me for a selection, and I hit 'q' for the Arrows of Wounding. The game then dies.
I'll have to look at the problem code, because I'm not sure why this would cause a buffer overflow. Though, given the inventory slot going from full to empty, I suspect there's a missing check for that condition.