[Scummvm-tracker] [ScummVM :: Bugs] #15945: NANCY: nancy7: Heap overrun in RippedLetterPuzzle
ScummVM :: Bugs
trac at scummvm.org
Sat May 24 14:33:13 UTC 2025
#15945: NANCY: nancy7: Heap overrun in RippedLetterPuzzle
------------------------------------------------+--------------------------
Reporter: tunnelsociety | Owner: (none)
Type: defect | Status: new
Priority: high | Component: Engine:
| Nancy
Version: | Keywords:
Game: Nancy Drew: Ghost Dogs of Moon Lake |
------------------------------------------------+--------------------------
A heap overrun occurs in Ghost Dogs of Moon Lake. Happens when trying to
save the game after attempting certain puzzles. For example, load scene
3415, the Combo Cola puzzle, then try to leave Em's Emporium [which
triggers a Second Chance save]. (Equally affects Roman Numerals puzzle at
the ranger station.)
These puzzles have fewer pieces than the RippedLetterPuzzle in nancy2 STFD
but the save code assumes a size.
Arigatou ASan:
{{{
=================================================================
==13509==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x603000173184 at pc 0x560144813b39 bp 0x7ffec6b35bf0 sp 0x7ffec6b35be8
READ of size 1 at 0x603000173184 thread T0
#0 0x560144813b38 in void Common::Serializer::syncAsByte<signed
char>(signed char&, unsigned int, unsigned int) common/serializer.h:117:2
#1 0x5601448108ea in void Common::Serializer::syncArray<signed
char>(signed char*, unsigned long, void (*)(Common::Serializer&, signed
char&), unsigned int, unsigned int) common/serializer.h:297:4
#2 0x56014480be23 in
Nancy::RippedLetterPuzzleData::synchronize(Common::Serializer&)
engines/nancy/puzzledata.cpp:76:6
#3 0x5601443bdc37 in
Nancy::State::Scene::synchronize(Common::Serializer&)
engines/nancy/state/scene.cpp:737:15
#4 0x56014474b4a4 in
Nancy::NancyEngine::synchronize(Common::Serializer&)
engines/nancy/nancy.cpp:662:18
#5 0x56014474ba6d in
Nancy::NancyEngine::saveGameStream(Common::WriteStream*, bool)
engines/nancy/nancy.cpp:119:9
#6 0x560144891f39 in Engine::saveGameState(int, Common::String const&,
bool) engines/engine.cpp:924:25
#7 0x56014474c404 in Nancy::NancyEngine::secondChance()
engines/nancy/nancy.cpp:136:2
#8 0x5601444e15bc in Nancy::Action::SaveContinueGame::execute()
engines/nancy/action/miscrecords.cpp:163:11
#9 0x56014446f25a in
Nancy::Action::ActionManager::processActionRecords()
engines/nancy/action/actionmanager.cpp:261:12
#10 0x5601443ab8a4 in Nancy::State::Scene::run()
engines/nancy/state/scene.cpp:1023:17
#11 0x5601447579b1 in Nancy::NancyEngine::run()
engines/nancy/nancy.cpp:318:7
...
0x603000173184 is located 0 bytes to the right of 20-byte region
[0x603000173170,0x603000173184)
allocated by thread T0 here:
#0 0x5601442cf07e in malloc (scummvm+0xec207e) (BuildId:
c37659539ee7296c)
#1 0x5601445de28d in Common::Array<signed
char>::allocCapacity(unsigned int) common/array.h:470:20
#2 0x5601445fd252 in Common::Array<signed
char>::operator=(Common::Array<signed char> const&) common/array.h:291:3
#3 0x5601445f195c in Nancy::Action::RippedLetterPuzzle::execute()
engines/nancy/action/puzzle/rippedletterpuzzle.cpp:206:24
#4 0x56014446f25a in
Nancy::Action::ActionManager::processActionRecords()
engines/nancy/action/actionmanager.cpp:261:12
#5 0x5601443ab8a4 in Nancy::State::Scene::run()
engines/nancy/state/scene.cpp:1023:17
#6 0x5601447579b1 in Nancy::NancyEngine::run()
engines/nancy/nancy.cpp:318:7
...
SUMMARY: AddressSanitizer: heap-buffer-overflow common/serializer.h:117:2
in void Common::Serializer::syncAsByte<signed char>(signed char&, unsigned
int, unsigned int)
Shadow bytes around the buggy address:
0x0c06800265e0: fd fd fd fa fa fa fd fd fd fa fa fa fd fd fd fd
0x0c06800265f0: fa fa fd fd fd fa fa fa fd fd fd fa fa fa fd fd
0x0c0680026600: fd fa fa fa fd fd fd fa fa fa fd fd fd fd fa fa
0x0c0680026610: fd fd fd fd fa fa fd fd fd fd fa fa fd fd fd fd
0x0c0680026620: fa fa fd fd fd fd fa fa fd fd fd fd fa fa 00 00
=>0x0c0680026630:[04]fa fa fa 00 00 04 fa fa fa fd fd fd fd fa fa
0x0c0680026640: fd fd fd fd fa fa fd fd fd fd fa fa fd fd fd fd
0x0c0680026650: fa fa fd fd fd fd fa fa fd fd fd fd fa fa fd fd
0x0c0680026660: fd fd fa fa fd fd fd fd fa fa fd fd fd fd fa fa
0x0c0680026670: fd fd fd fd fa fa fd fd fd fd fa fa fd fd fd fd
0x0c0680026680: fa fa fd fd fd fd fa fa fd fd fd fd fa fa fd fd
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
==13509==ABORTING
}}}
My probably unacceptable hotfix to keep playing on my build was:
{{{#!diff
diff --git a/engines/nancy/puzzledata.cpp b/engines/nancy/puzzledata.cpp
index b17fe76a763..2a18862b4a1 100644
--- a/engines/nancy/puzzledata.cpp
+++ b/engines/nancy/puzzledata.cpp
@@ -58,9 +58,11 @@ RippedLetterPuzzleData::RippedLetterPuzzleData() :
playerHasTriedPuzzle(false) {}
void RippedLetterPuzzleData::synchronize(Common::Serializer &ser) {
+ const int numPieces = g_nancy->getGameType() == kGameTypeNancy7 ?
20 : 24;
+
if (ser.isLoading()) {
- order.resize(24);
- rotations.resize(24);
+ order.resize(numPieces);
+ rotations.resize(numPieces);
} else {
// A piece may still be held while saving; make sure the
saved data
// has it back in the last place it was picked up from
@@ -73,8 +75,8 @@ void
RippedLetterPuzzleData::synchronize(Common::Serializer &ser) {
}
}
- ser.syncArray(order.data(), 24, Common::Serializer::Byte);
- ser.syncArray(rotations.data(), 24, Common::Serializer::Byte);
+ ser.syncArray(order.data(), numPieces, Common::Serializer::Byte);
+ ser.syncArray(rotations.data(), numPieces,
Common::Serializer::Byte);
}
TowerPuzzleData::TowerPuzzleData() {
```
--
Ticket URL: <https://bugs.scummvm.org/ticket/15945>
ScummVM :: Bugs <https://bugs.scummvm.org>
ScummVM
More information about the Scummvm-tracker
mailing list