phpv8 / v8js

V8 Javascript Engine for PHP — This PHP extension embeds the Google V8 Javascript Engine
http://pecl.php.net/package/v8js
MIT License
1.84k stars 200 forks source link

Create Snapshot Currently Sigfaults with Malformed Data - Add Capability to throw new Snapshot Exception #223

Closed virgofx closed 8 years ago

virgofx commented 8 years ago

The new snapshot feature works great. Would it be possible to update the API to have createSnapshot() throw exception on failure. During testing I have malformed script (or something that doesn't work great on server), yet very hard to debug. It currently throws sigfault crashing PHP with 502.

I'm not sure what types of exceptions can be caught during creation of the snapshot; however, the more the better. If this could be done that would be very helpful.

Current Backtrace

Program received signal SIGILL, Illegal instruction.
0x00007fc80e4857cf in v8::base::OS::Abort() () from /usr/lib/libv8.so
(gdb) bt
#0  0x00007fc80e4857cf in v8::base::OS::Abort() () from /usr/lib/libv8.so
#1  0x0000003000000020 in ?? ()
#2  0x00007fff1fec1240 in ?? ()
#3  0x00007fff1fec1160 in ?? ()
#4  0x00007fff1fec1ac0 in ?? ()
#5  0x00001e2779504ab0 in ?? ()
#6  0x00007fc80e3b3f48 in v8::internal::SnapshotByteSink::PutRaw(unsigned char const*, int, char const*) () from /usr/lib/libv8.so
#7  0x00007fc80e3ad811 in v8::internal::Serializer::ObjectSerializer::OutputRawData(unsigned char*, v8::internal::Serializer::ObjectSerializer::ReturnSkip) ()
   from /usr/lib/libv8.so
#8  0x00007fc80e3ad525 in v8::internal::Serializer::ObjectSerializer::Serialize() () from /usr/lib/libv8.so
#9  0x00007fc80e3b43a7 in v8::internal::StartupSerializer::SerializeObject(v8::internal::HeapObject*, v8::internal::SerializerDeserializer::HowToCode, v8::internal::SerializerDeserializer::WhereToPoint, int) () from /usr/lib/libv8.so
#10 0x00007fc80e3ada4c in v8::internal::Serializer::ObjectSerializer::VisitPointers(v8::internal::Object**, v8::internal::Object**) () from /usr/lib/libv8.so
#11 0x00007fc80e3ad503 in v8::internal::Serializer::ObjectSerializer::Serialize() () from /usr/lib/libv8.so
#12 0x00007fc80e3b431d in v8::internal::StartupSerializer::SerializeObject(v8::internal::HeapObject*, v8::internal::SerializerDeserializer::HowToCode, v8::internal::SerializerDeserializer::WhereToPoint, int) () from /usr/lib/libv8.so
#13 0x00007fc80e3ada4c in v8::internal::Serializer::ObjectSerializer::VisitPointers(v8::internal::Object**, v8::internal::Object**) () from /usr/lib/libv8.so
#14 0x00007fc80e3ad503 in v8::internal::Serializer::ObjectSerializer::Serialize() () from /usr/lib/libv8.so
#15 0x00007fc80e3b431d in v8::internal::StartupSerializer::SerializeObject(v8::internal::HeapObject*, v8::internal::SerializerDeserializer::HowToCode, v8::internal::SerializerDeserializer::WhereToPoint, int) () from /usr/lib/libv8.so
#16 0x00007fc80e3ada4c in v8::internal::Serializer::ObjectSerializer::VisitPointers(v8::internal::Object**, v8::internal::Object**) () from /usr/lib/libv8.so
#17 0x00007fc80e3ad503 in v8::internal::Serializer::ObjectSerializer::Serialize() () from /usr/lib/libv8.so
#18 0x00007fc80e3b431d in v8::internal::StartupSerializer::SerializeObject(v8::internal::HeapObject*, v8::internal::SerializerDeserializer::HowToCode, v8::internal::SerializerDeserializer::WhereToPoint, int) () from /usr/lib/libv8.so
#19 0x00007fc80e3ada4c in v8::internal::Serializer::ObjectSerializer::VisitPointers(v8::internal::Object**, v8::internal::Object**) () from /usr/lib/libv8.so
#20 0x00007fc80e3ad503 in v8::internal::Serializer::ObjectSerializer::Serialize() () from /usr/lib/libv8.so
#21 0x00007fc80e3b431d in v8::internal::StartupSerializer::SerializeObject(v8::internal::HeapObject*, v8::internal::SerializerDeserializer::HowToCode, v8::internal::SerializerDeserializer::WhereToPoint, int) () from /usr/lib/libv8.so
#22 0x00007fc80e3ada4c in v8::internal::Serializer::ObjectSerializer::VisitPointers(v8::internal::Object**, v8::internal::Object**) () from /usr/lib/libv8.so
#23 0x00007fc80e3ad503 in v8::internal::Serializer::ObjectSerializer::Serialize() () from /usr/lib/libv8.so
#24 0x00007fc80e3b431d in v8::internal::StartupSerializer::SerializeObject(v8::internal::HeapObject*, v8::internal::SerializerDeserializer::HowToCode, v8::internal::SerializerDeserializer::WhereToPoint, int) () from /usr/lib/libv8.so
#25 0x00007fc80e3ada4c in v8::internal::Serializer::ObjectSerializer::VisitPointers(v8::internal::Object**, v8::internal::Object**) () from /usr/lib/libv8.so
#26 0x00007fc80e3ad503 in v8::internal::Serializer::ObjectSerializer::Serialize() () from /usr/lib/libv8.so
#27 0x00007fc80e3b431d in v8::internal::StartupSerializer::SerializeObject(v8::internal::HeapObject*, v8::internal::SerializerDeserializer::HowToCode, v8::internal::SerializerDeserializer::WhereToPoint, int) () from /usr/lib/libv8.so
#28 0x00007fc80e3b4774 in v8::internal::StartupSerializer::VisitPointers(v8::internal::Object**, v8::internal::Object**) () from /usr/lib/libv8.so
#29 0x00007fc80e1ac660 in v8::internal::Heap::IterateStrongRoots(v8::internal::ObjectVisitor*, v8::internal::VisitMode) () from /usr/lib/libv8.so
#30 0x00007fc80ded457a in v8::V8::CreateSnapshotDataBlob(char const*) () from /usr/lib/libv8.so
#31 0x00007fc80e6756b4 in zim_V8Js_createSnapshot (ht=<optimized out>, return_value=0x22fb068, return_value_ptr=<optimized out>, this_ptr=<optimized out>, 
    return_value_used=<optimized out>) at /tmp/pear/temp/v8js/v8js_class.cc:1113
#32 0x00000000006cb1ab in dtrace_execute_internal ()
#33 0x00007fc816fa3ed7 in xdebug_execute_internal (current_execute_data=0x7fc819fb5c48, fci=0x0, return_value_used=1)
    at /build/xdebug-9v1f9t/xdebug-2.3.3/xdebug-2.3.3/xdebug.c:1767
#34 0x0000000000780624 in ?? ()
#35 0x0000000000716178 in execute_ex ()
#36 0x00000000006cb0a9 in dtrace_execute_ex ()
#37 0x00007fc816fa3642 in xdebug_execute_ex (execute_data=0x7fc819fb5c48) at /build/xdebug-9v1f9t/xdebug-2.3.3/xdebug-2.3.3/xdebug.c:1644
#38 0x0000000000780b47 in ?? ()
#39 0x0000000000716178 in execute_ex ()
#40 0x00000000006cb0a9 in dtrace_execute_ex ()
#41 0x00007fc816fa3642 in xdebug_execute_ex (execute_data=0x7fc819fb51e8) at /build/xdebug-9v1f9t/xdebug-2.3.3/xdebug-2.3.3/xdebug.c:1644
#42 0x0000000000780b47 in ?? ()
#43 0x0000000000716178 in execute_ex ()
#44 0x00000000006cb0a9 in dtrace_execute_ex ()
#45 0x00007fc816fa3642 in xdebug_execute_ex (execute_data=0x7fc819fb47f0) at /build/xdebug-9v1f9t/xdebug-2.3.3/xdebug-2.3.3/xdebug.c:1644
#46 0x0000000000780b47 in ?? ()
#47 0x0000000000716178 in execute_ex ()
#48 0x00000000006cb0a9 in dtrace_execute_ex ()
#49 0x00007fc816fa3642 in xdebug_execute_ex (execute_data=0x7fc819fb4688) at /build/xdebug-9v1f9t/xdebug-2.3.3/xdebug-2.3.3/xdebug.c:1644
#50 0x00007fc80c26deb3 in zephir_require_ret () from /usr/lib/php5/20131226/phalcon.so
#51 0x00007fc80c57f783 in zim_Phalcon_Mvc_View_Engine_Php_render () from /usr/lib/php5/20131226/phalcon.so
#52 0x00000000006cb1ab in dtrace_execute_internal ()
#53 0x00007fc816fa3ed7 in xdebug_execute_internal (current_execute_data=0x7fff1fec2c90, fci=0x7fff1fec2bf0, return_value_used=1)
    at /build/xdebug-9v1f9t/xdebug-2.3.3/xdebug-2.3.3/xdebug.c:1767
#54 0x00007fc80c27769f in zephir_call_user_function () from /usr/lib/php5/20131226/phalcon.so
#55 0x00007fc80c28e34f in zephir_call_class_method_aparams () from /usr/lib/php5/20131226/phalcon.so
#56 0x00007fc80c56c8c1 in zim_Phalcon_Mvc_View__engineRender () from /usr/lib/php5/20131226/phalcon.so
#57 0x00000000006cb1ab in dtrace_execute_internal ()
#58 0x00007fc816fa3ed7 in xdebug_execute_internal (current_execute_data=0x7fc819fb4190, fci=0x0, return_value_used=0)
    at /build/xdebug-9v1f9t/xdebug-2.3.3/xdebug-2.3.3/xdebug.c:1767
#59 0x0000000000780624 in ?? ()
#60 0x0000000000716178 in execute_ex ()
#61 0x00000000006cb0a9 in dtrace_execute_ex ()
#62 0x00007fc816fa3642 in xdebug_execute_ex (execute_data=0x7fc819fb4190) at /build/xdebug-9v1f9t/xdebug-2.3.3/xdebug-2.3.3/xdebug.c:1644
#63 0x00007fc80c276774 in zephir_call_user_function () from /usr/lib/php5/20131226/phalcon.so
#64 0x00007fc80c28e34f in zephir_call_class_method_aparams () from /usr/lib/php5/20131226/phalcon.so
#65 0x00007fc80c47227b in zim_Phalcon_Mvc_Application_handle () from /usr/lib/php5/20131226/phalcon.so
#66 0x00000000006cb1ab in dtrace_execute_internal ()
#67 0x00007fc816fa3ed7 in xdebug_execute_internal (current_execute_data=0x7fc819fb2540, fci=0x0, return_value_used=1)
    at /build/xdebug-9v1f9t/xdebug-2.3.3/xdebug-2.3.3/xdebug.c:1767
#68 0x0000000000780624 in ?? ()
#69 0x0000000000716178 in execute_ex ()
#70 0x00000000006cb0a9 in dtrace_execute_ex ()
#71 0x00007fc816fa3642 in xdebug_execute_ex (execute_data=0x7fc819fb2540) at /build/xdebug-9v1f9t/xdebug-2.3.3/xdebug-2.3.3/xdebug.c:1644
#72 0x0000000000780b47 in ?? ()
#73 0x0000000000716178 in execute_ex ()
#74 0x00000000006cb0a9 in dtrace_execute_ex ()
#75 0x00007fc816fa3642 in xdebug_execute_ex (execute_data=0x7fc819fb15f0) at /build/xdebug-9v1f9t/xdebug-2.3.3/xdebug-2.3.3/xdebug.c:1644
#76 0x00000000006dd450 in zend_execute_scripts ()
#77 0x000000000067b5c2 in php_execute_script ()
#78 0x0000000000464841 in main ()
stesie commented 8 years ago

V8 aborts the process itself here, there's nothing the extension could do about.

Do you have the JS payload that triggers the crash? Could you please try running mksnapshot manually with that source code ... I suppose it crashes there as well (if the same source code crashes repeatedly)

... which version of V8 are you using? Maybe just pick a (slighly) newer one

virgofx commented 8 years ago

Well I found the single character that was causing the payload to crash. It was currently using "–" Either the symbol or the entity code that is "&" + "ndash;" I believe other entities as well make it crash. I'm reinstalling manually (instead of using precompiled binaries) to test the mksnapshot utility to see if it behaves any differently

virgofx commented 8 years ago

I took your advice and upgraded from 5.1.53 to 5.1.256 and it looks like they've fixed a lot of unicode issues (in the change logs) -- which also now work in server side version and allow the entities in JSX (e.g. ampersand + other chracters)

As far as reporting errors, I was just wondering if it were possible to wrap the create snapshot in C-land to prevent the sigfault if possible. If it's not, that's fine too as it's a user issue when the payload is corrupted and this can be closed.

Thanks @stesie

stesie commented 8 years ago

no, there's no way for a caller (V8Js) to handle execution of illegal instructions by a called library (at least not a porable one). After all V8 probably corrupted its memory layout by doing that ... so even if it would like to, V8Js couldn't continue it's work.

and after all, that clearly is a bug within V8 so there shouldn't be facades hiding it