Samsung / escargot

Escargot is a lightweight JavaScript engine designed specifically for resource-constrained environments.
GNU Lesser General Public License v2.1
268 stars 43 forks source link

stack-overflow in Escargot::ObjectStructureWithoutTransition::lastFoundPropertyIndex #1316

Closed Ye0nny closed 7 months ago

Ye0nny commented 9 months ago

Escargot

Build Steps

cmake -DCMAKE_CXX_FLAGS=-fsanitize=address -DESCARGOT_MODE=debug -DESCARGOT_OUTPUT=shell -GNinja

Describe the bug Stack overflow

Test case

testcase

```javascript var var0 = { }, e = this ; e. __defineSetter__ ( " set x ", function ( func0 ) { x = e ; }, this. __proto__ = e ) ; " global. x = 0 " in e ; this in this ; RangeError ; ```

// poc.js
var e = this ;
e. __defineSetter__ ( " ", function ( func0 ) { }, this. __proto__ = e ) ;
" global. x = 0 " in e ;

Execution steps & Output

$ ./escargot poc.js
ddressSanitizer:DEADLYSIGNAL
=================================================================
==15767==ERROR: AddressSanitizer: stack-overflow on address 0x7ffd70ca5fe8 (pc 0x564afc55f79b bp 0x7ffd70ca6070 sp 0x7ffd70ca5fe0 T0)
    #0 0x564afc55f79a in Escargot::ObjectStructureWithoutTransition::lastFoundPropertyIndex() src/runtime/ObjectStructure.h:261
    #1 0x564afc560c92 in Escargot::ObjectStructureWithoutTransition::findProperty(Escargot::ObjectStructurePropertyName const&) src/runtime/ObjectStructure.cpp:83
    #2 0x564afc53989c in Escargot::Object::getOwnProperty(Escargot::ExecutionState&, Escargot::ObjectPropertyName const&) src/runtime/Object.cpp:758
    #3 0x564afc4c06f8 in Escargot::GlobalObject::getOwnProperty(Escargot::ExecutionState&, Escargot::ObjectPropertyName const&) src/runtime/GlobalObject.cpp:143
    #4 0x564afc53d1bf in Escargot::Object::hasProperty(Escargot::ExecutionState&, Escargot::ObjectPropertyName const&) src/runtime/Object.cpp:1021
    #5 0x564afc4bfffb in Escargot::GlobalObject::hasProperty(Escargot::ExecutionState&, Escargot::ObjectPropertyName const&) src/runtime/GlobalObject.cpp:122
    #6 0x564afc4cde56 in Escargot::GlobalObjectProxyObject::hasProperty(Escargot::ExecutionState&, Escargot::ObjectPropertyName const&) src/runtime/GlobalObjectProxyObject.cpp:52
    #7 0x564afc53d2e1 in Escargot::Object::hasProperty(Escargot::ExecutionState&, Escargot::ObjectPropertyName const&) src/runtime/Object.cpp:1032
    #8 0x564afc4bfffb in Escargot::GlobalObject::hasProperty(Escargot::ExecutionState&, Escargot::ObjectPropertyName const&) src/runtime/GlobalObject.cpp:122
    #9 0x564afc4cde56 in Escargot::GlobalObjectProxyObject::hasProperty(Escargot::ExecutionState&, Escargot::ObjectPropertyName const&) src/runtime/GlobalObjectProxyObject.cpp:52
    ...
    ...
    #242 0x564afc4bfffb in Escargot::GlobalObject::hasProperty(Escargot::ExecutionState&, Escargot::ObjectPropertyName const&) src/runtime/GlobalObject.cpp:122
    #243 0x564afc4cde56 in Escargot::GlobalObjectProxyObject::hasProperty(Escargot::ExecutionState&, Escargot::ObjectPropertyName const&) src/runtime/GlobalObjectProxyObject.cpp:52
    #244 0x564afc53d2e1 in Escargot::Object::hasProperty(Escargot::ExecutionState&, Escargot::ObjectPropertyName const&) src/runtime/Object.cpp:1032
    #245 0x564afc4bfffb in Escargot::GlobalObject::hasProperty(Escargot::ExecutionState&, Escargot::ObjectPropertyName const&) src/runtime/GlobalObject.cpp:122
    #246 0x564afc4cde56 in Escargot::GlobalObjectProxyObject::hasProperty(Escargot::ExecutionState&, Escargot::ObjectPropertyName const&) src/runtime/GlobalObjectProxyObject.cpp:52
    #247 0x564afc53d2e1 in Escargot::Object::hasProperty(Escargot::ExecutionState&, Escargot::ObjectPropertyName const&) src/runtime/Object.cpp:1032
    #248 0x564afc4bfffb in Escargot::GlobalObject::hasProperty(Escargot::ExecutionState&, Escargot::ObjectPropertyName const&) src/runtime/GlobalObject.cpp:122

SUMMARY: AddressSanitizer: stack-overflow src/runtime/ObjectStructure.h:261 in Escargot::ObjectStructureWithoutTransition::lastFoundPropertyIndex()
==15767==ABORTING

when executed in release mode

Output

Segmentation fault

Expected behavior We would expect to detect a TypeError at prototype. Because it refers to itself as the prototype of the 'e' object.

e. __defineSetter__ ( " ", function ( func0 ) { }, this. __proto__ = e ) ;
                                                                   ^

Credits: @Ye0nny, @EJueon