Details
-
Bug
-
Resolution: Fixed
-
P1: Critical
-
6.2.3, 6.4.2
-
None
-
-
63b622d59 (dev), 0cec81ec0 (6.6), b1af4d9db (6.5), fa00e3943 (tqtc/lts-6.2)
Description
The attached tarball contains a stripped down example implementation of "proxy autoconf" using a JavaScript snippet, containing a function, which when called, causes QV4 to crash in various ways depending on the toolchain/platform. If you untar and run 'qmake && make && ./pac-test', it will crash. It looks like it's the second invoke that crashes, after the first invoke worked as expected.
The issue is problematic for the "proxy autoconf" feature - as this feature is based on downloading a third party js snippet and executing this locally. We therefore can't predict whether any particular js file will cause this crash - but we do see the same backtrace whenever this happens.
The tarball's main.cpp contains the javascript snipped defined in "pacstring". Many strange modifications can be made to seemingly make the issue disappear, including but not limited to:
1. Removing the std::async/future.get invocation
2. Removing the declaration and implementation of three unused functions: PACHelper::isPlainHostName, PACHelper::localHostOrDomainIs and PACHelper::isResolvable
With 6.2.3 and 6.4.2, the backtrace is something like this (see below for an ARM target backtrace):
Thread 3 "pac-test" received signal SIGSEGV, Segmentation fault. [Switching to Thread 0x7ffff31bb6c0 (LWP 2291678)] 0x00007ffff7bd6ffc in QV4::Heap::QObjectMethod::metaObject (this=0x7ffff3201e20) at /usr/src/qt6-declarative-6.4.2+dfsg-1/src/qml/jsruntime/qv4qobjectwrapper.cpp:2158 Downloading source file /usr/src/qt6-declarative-6.4.2+dfsg-1/src/qml/jsruntime/qv4qobjectwrapper.cpp 2158 return object()->metaObject(); (gdb) bt #0 0x00007ffff7bd6ffc in QV4::Heap::QObjectMethod::metaObject (this=0x7ffff3201e20) at /usr/src/qt6-declarative-6.4.2+dfsg-1/src/qml/jsruntime/qv4qobjectwrapper.cpp:2158 #1 QV4::Heap::QObjectMethod::metaObject (this=0x7ffff3201e20) at /usr/src/qt6-declarative-6.4.2+dfsg-1/src/qml/jsruntime/qv4qobjectwrapper.cpp:2154 #2 QV4::Heap::QObjectMethod::ensureMethodsCache (this=0x7ffff3201e20) at /usr/src/qt6-declarative-6.4.2+dfsg-1/src/qml/jsruntime/qv4qobjectwrapper.cpp:2165 #3 QV4::Heap::QObjectMethod::ensureMethodsCache (this=0x7ffff3201e20) at /usr/src/qt6-declarative-6.4.2+dfsg-1/src/qml/jsruntime/qv4qobjectwrapper.cpp:2161 #4 QV4::QObjectMethod::callInternal (this=0x7ffff37bf5d8, thisObject=0x7ffff37bf5c8, argv=0x7ffff37bf500, argc=0) at /usr/src/qt6-declarative-6.4.2+dfsg-1/src/qml/jsruntime/qv4qobjectwrapper.cpp:2262 #5 0x00007ffff7beec36 in QV4::Runtime::CallName::call (engine=0x55555557b200, nameIndex=19, argv=0x7ffff37bf500, argc=0) at /usr/src/qt6-declarative-6.4.2+dfsg-1/src/qml/jsruntime/qv4runtime.cpp:1437 #6 0x00007ffff7c1d7ec in QV4::Moth::VME::interpret (frame=0x7ffff31ba940, engine=0x55555557b200, code=0x7fffec029d3f "\016\002") at /usr/src/qt6-declarative-6.4.2+dfsg-1/src/qml/jsruntime/qv4vme_moth.cpp:872 #7 0x00007ffff7c23aac in QV4::Moth::VME::exec (frame=<optimized out>, engine=<optimized out>) at /usr/src/qt6-declarative-6.4.2+dfsg-1/src/qml/jsruntime/qv4vme_moth.cpp:542 #8 0x00007ffff7b9b2b0 in QV4::ArrowFunction::virtualCall (fo=<optimized out>, thisObject=<optimized out>, argv=<optimized out>, argc=<optimized out>) at /usr/src/qt6-declarative-6.4.2+dfsg-1/src/qml/jsruntime/qv4functionobject.cpp:537 #9 0x00007ffff7b4f644 in QV4::FunctionObject::call (data=..., this=0x7ffff7fbe040) at /usr/src/qt6-declarative-6.4.2+dfsg-1/obj-x86_64-linux-gnu/include/QtQml/6.4.2/QtQml/private/../../../../../../src/qml/jsruntime/qv4jscall_p.h:96
On one of our ARM targets, we were able to run valgrind, and got a similar backtrace:
Warning: Permanently added '10.47.90.51' (RSA) to the list of known hosts. ==18532== Memcheck, a memory error detector ==18532== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al. ==18532== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info ==18532== Command: /bin/pacmanager -t /run/pac/home/kgledits/src/main/cvise2/testfile.pac -d ==18532== 0 => Error: Insufficient arguments ==18532== Thread 2: ==18532== Invalid read of size 8 ==18532== at 0x4A9B180: QV4::Heap::QObjectMethod::ensureMethodsCache() [clone .part.0] (in /lib/libQt6Qml.so.6.2.3) ==18532== by 0x4AA2E9F: QV4::QObjectMethod::callInternal(QV4::Value const*, QV4::Value const*, int) const (in /lib/libQt6Qml.so.6.2.3) ==18532== by 0x4ABE45F: QV4::Runtime::CallName::call(QV4::ExecutionEngine*, int, QV4::Value*, int) (in /lib/libQt6Qml.so.6.2.3) ==18532== by 0x4AEF6FB: QV4::Moth::VME::interpret(QV4::JSTypesStackFrame*, QV4::ExecutionEngine*, char const*) (in /lib/libQt6Qml.so.6.2.3) ==18532== by 0x4AF2C5F: QV4::Moth::VME::exec(QV4::JSTypesStackFrame*, QV4::ExecutionEngine*) (in /lib/libQt6Qml.so.6.2.3) ==18532== by 0x4A5AB97: QV4::ArrowFunction::virtualCall(QV4::FunctionObject const*, QV4::Value const*, QV4::Value const*, int) (in /lib/libQt6Qml.so.6.2.3) ==18532== by 0x4A03217: QJSValue::call(QList<QJSValue> const&) const (in /lib/libQt6Qml.so.6.2.3) ==18532== by 0x116B1F: ProxyAutoConf::findProxyForUrl(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (in /bin/pacmanager) ==18532== by 0x113A1B: Service::processUrl(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (in /bin/pacmanager) ==18532== by 0x1165CB: std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > (Service::*)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), Service*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::operator()() const (in /bin/pacmanager) ==18532== by 0x1166EB: std::_Function_handler<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> (), std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > (Service::*)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), Service*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::_M_invoke(std::_Any_data const&) (in /bin/pacmanager) ==18532== by 0x11421F: std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*) (in /bin/pacmanager) ==18532== Address 0x0 is not stack'd, malloc'd or (recently) free'd