Bug 444003 - kjsapitest segmentation fault (UB)
Summary: kjsapitest segmentation fault (UB)
Status: RESOLVED FIXED
Alias: None
Product: frameworks-kjs
Classification: Frameworks and Libraries
Component: general (show other bugs)
Version: 5.87.0
Platform: Compiled Sources Linux
: NOR normal
Target Milestone: ---
Assignee: Bernd Buschinski
URL:
Keywords:
: 444004 444005 444006 (view as bug list)
Depends on:
Blocks:
 
Reported: 2021-10-18 23:39 UTC by James Beddek
Modified: 2021-11-25 23:29 UTC (History)
4 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description James Beddek 2021-10-18 23:39:45 UTC
Application: okular (5.18.2 (21.08.2))
 (Compiled from sources)
Qt Version: 5.15.2
Frameworks Version: 5.87.0
Operating System: Linux 5.14.12-gentoo-dist x86_64
Windowing System: X11
Distribution: Gentoo Linux
DrKonqi: 5.23.0 [KCrashBackend]
Compiler: Clang 13.0.0
C{,XX}FLAGS: -march=znver2 -O3 -glldb -fPIC -fstack-protector-strong -D_FORTIFY_SOURCE=2 -pipe

-- Information about the crash:
- What I was doing when the application crashed:

Running tests.

The crash can be reproduced every time.

-- Backtrace:
Application: kjsfunctionstest (kjsfunctionstest), signal: Segmentation fault

[KCrash Handler]
#4  KJS::JSCell::isObject (this=0x3) at /usr/src/debug/kde-frameworks/kjs-5.87.0/kjs-5.87.0/src/kjs/value.h:319
#5  KJS::JSValue::isObject (this=0x3) at /usr/src/debug/kde-frameworks/kjs-5.87.0/kjs-5.87.0/src/kjs/value.h:377
#6  KJS::JSObject::put (this=0x7f41e68d09c0, exec=0x559956d1fe20, propertyName=..., value=0x7f41e68d0a00, attr=4) at /usr/src/debug/kde-frameworks/kjs-5.87.0/kjs-5.87.0/src/kjs/object.cpp:247
#7  0x00007f41eb0b2a98 in KJS::ErrorPrototype::ErrorPrototype (this=0x7f41e68d09c0, exec=0x559956d1fe20, objectProto=<optimized out>, funcProto=0x7f41e68d00c0) at /usr/src/debug/kde-frameworks/kjs-5.87.0/kjs-5.87.0/src/kjs/error_object.cpp:53
#8  0x00007f41eb0bc0fc in KJS::Interpreter::initGlobalObject (this=0x559956d1fe00) at /usr/src/debug/kde-frameworks/kjs-5.87.0/kjs-5.87.0/src/kjs/interpreter.cpp:385
#9  0x00007f41ecb275ff in KJSInterpreter::KJSInterpreter (this=0x559956d1fde0, global=...) at /usr/src/debug/kde-frameworks/kjs-5.87.0/kjs-5.87.0/src/kjs/api/kjsinterpreter.cpp:111
#10 0x00007f41ee0525f9 in Okular::ExecutorKJSPrivate::initTypes (this=this@entry=0x559956d1f910) at /var/tmp/portage/kde-apps/okular-21.08.2/work/okular-21.08.2/core/script/executor_kjs.cpp:60
#11 0x00007f41ee05294c in Okular::ExecutorKJSPrivate::ExecutorKJSPrivate (this=0x559956d1f910, doc=0x559956c36060) at /var/tmp/portage/kde-apps/okular-21.08.2/work/okular-21.08.2/core/script/executor_kjs.cpp:43
#12 Okular::ExecutorKJS::ExecutorKJS (this=0x559956d1f7c0, doc=0x559956c36060) at /var/tmp/portage/kde-apps/okular-21.08.2/work/okular-21.08.2/core/script/executor_kjs.cpp:89
#13 0x00007f41ee01adeb in Okular::Scripter::execute (this=0x559956d1f780, type=Okular::JavaScript, script=...) at /var/tmp/portage/kde-apps/okular-21.08.2/work/okular-21.08.2/core/scripter.cpp:65
#14 0x00007f41edfe6d15 in Okular::Document::processAction (this=0x559956c2e730, action=0x559956d1e680) at /var/tmp/portage/kde-apps/okular-21.08.2/work/okular-21.08.2/core/document.cpp:4012
#15 0x00005599569b4bdb in KJSFunctionsTest::testNthFieldName (this=0x7ffea87a03a0) at /var/tmp/portage/kde-apps/okular-21.08.2/work/okular-21.08.2/autotests/kjsfunctionstest.cpp:124
#16 0x00007f41ed7c04ff in QMetaMethod::invoke (this=0x559956c2ec80, object=0x7ffea87a03a0, connectionType=<optimized out>, returnValue=..., val0=..., val1=..., val2=..., val3=..., val4=..., val5=..., val6=..., val7=..., val8=..., val9=...) at /usr/src/debug/dev-qt/qtcore-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qmetaobject.cpp:2303
#17 0x00007f41ee090d5d in QMetaMethod::invoke (this=<optimized out>, object=0x559956d1fe20, object@entry=0x0, connectionType=Qt::DirectConnection, val0=..., val1=..., val2=..., val3=..., val4=..., val5=..., val6=..., val7=..., val8=..., val9=...) at ../../include/QtCore/../../../qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qmetaobject.h:122
#18 QTest::TestMethods::invokeTestOnData (this=this@entry=0x7ffea87a0280, index=index@entry=0) at /usr/src/debug/dev-qt/qttest-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/testlib/qtestcase.cpp:938
#19 0x00007f41ee0917d8 in QTest::TestMethods::invokeTest (this=this@entry=0x7ffea87a0280, index=index@entry=0, data=data@entry=0x0, watchDog=watchDog@entry=0x559956c2e750) at /usr/src/debug/dev-qt/qttest-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/testlib/qtestcase.cpp:1166
#20 0x00007f41ee09270a in QTest::TestMethods::invokeTests (this=this@entry=0x7ffea87a0280, testObject=0x7ffea87a03a0) at /usr/src/debug/dev-qt/qttest-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/testlib/qtestcase.cpp:1507
#21 0x00007f41ee092d55 in QTest::qRun () at /usr/src/debug/dev-qt/qttest-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/testlib/qtestcase.cpp:1934
#22 0x00007f41ee092a1e in QTest::qExec (testObject=testObject@entry=0x7ffea87a03a0, argc=<optimized out>, argv=argv@entry=0x7ffea87a04e8) at /usr/src/debug/dev-qt/qttest-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/testlib/qtestcase.cpp:1842
#23 0x00005599569b73f9 in main (argc=1456602656, argv=0x7ffea87a04e8) at /var/tmp/portage/kde-apps/okular-21.08.2/work/okular-21.08.2/autotests/kjsfunctionstest.cpp:355
[Inferior 1 (process 2974076) detached]
Comment 1 Albert Astals Cid 2021-10-19 20:07:43 UTC
*** Bug 444004 has been marked as a duplicate of this bug. ***
Comment 2 Albert Astals Cid 2021-10-19 20:07:59 UTC
*** Bug 444005 has been marked as a duplicate of this bug. ***
Comment 3 Albert Astals Cid 2021-10-19 20:08:25 UTC
*** Bug 444006 has been marked as a duplicate of this bug. ***
Comment 4 Albert Astals Cid 2021-10-19 20:15:12 UTC
Your KJS compilation is likely broken, not something us Okular developers can really help with
Comment 5 James Beddek 2021-10-19 22:15:11 UTC
Hi Albert, it seems you might be on track there.
Recompiling kde-frameworks/kjs-5.87.0 with GCC allows kjs's "kjsapitest" test to pass where before it would fail if built with Clang.

When I build okular with GCC instead of Clang, the tests continue to fail if kjs was built with Clang. However, if kjs is built with GCC, and okular still with Clang, the tests pass.

I would say kjs is interpreting/parsing some tests incorrectly if itself was built with Clang.

Perhaps this should be passed on to the kjs people?

Thanks.
Comment 6 Albert Astals Cid 2021-10-20 20:46:16 UTC
Any chance you can try using a release clang instead of an unreleased one?
Comment 7 Albert Astals Cid 2021-10-20 20:47:03 UTC
Oh clang 13 was just release recently, apologies.
Comment 8 Albert Astals Cid 2021-10-20 20:51:09 UTC
I can't reproduce crash for what is worth (clang 12), does dropping the -march help?
Comment 9 James Beddek 2021-10-27 06:54:45 UTC
> I can't reproduce crash for what is worth (clang 12), does dropping the -march help?

The tests still crash without any -march option. Even with -01, the tests fail, but with -O0 they pass.
Comment 10 James Beddek 2021-10-28 02:22:39 UTC
I did a bisect of Clang/LLVM as the tests pass on 12.0.1, but not 13.0.0. That led me to this commit: https://github.com/llvm/llvm-project/commit/0aa0458f1429372038ca6a4edc7e94c96cd9a753

Which has issues with thunks: https://reviews.llvm.org/D100388

That is seemingly in progress but has no progress in many months.

Below is the "kjsapitest" test ran with ubsan and Clang 12.0.1:

/home/telans/src/kde/kjs/src/kjs/object.cpp:247:27: runtime error: member call on misaligned address 0x000000000003 for type 'KJS::JSValue', which requires 8 byte alignment
0x000000000003: note: pointer points here
<memory cannot be printed>
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /home/telans/src/kde/kjs/src/kjs/object.cpp:247:27 in
UndefinedBehaviorSanitizer:DEADLYSIGNAL
==2158002==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x000000000003 (pc 0x7f92776b4c1f bp 0x7fff485b9990 sp 0x7fff485b9680 T2158002)
==2158002==The signal is caused by a READ memory access.
==2158002==Hint: address points to the zero page.
    #0 0x7f92776b4c1f in KJS::JSObject::put(KJS::ExecState*, KJS::Identifier const&, KJS::JSValue*, int) /home/telans/src/kde/kjs/src/kjs/object.cpp:247:27
    #1 0x7f9277685633 in KJS::ErrorPrototype::ErrorPrototype(KJS::ExecState*, KJS::ObjectPrototype*, KJS::FunctionPrototype*) /home/telans/src/kde/kjs/src/kjs/error_object.cpp:53:5
    #2 0x7f92776c5d13 in KJS::Interpreter::initGlobalObject() /home/telans/src/kde/kjs/src/kjs/interpreter.cpp:385:38
    #3 0x7f92776c40c7 in KJS::Interpreter::init() /home/telans/src/kde/kjs/src/kjs/interpreter.cpp:270:5
    #4 0x7f92776c44aa in KJS::Interpreter::Interpreter() /home/telans/src/kde/kjs/src/kjs/interpreter.cpp:231:5
    #5 0x7f92784701c6 in KJSInterpreter::KJSInterpreter() /home/telans/src/kde/kjs/src/kjs/api/kjsinterpreter.cpp:99:27
    #6 0x23cd61 in KJSApiTest::objectConstruction() /home/telans/src/kde/kjs/autotests/kjsapitest.cpp:48:20
    #7 0x240059 in KJSApiTest::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) /home/telans/src/kde/kjs/build/autotests/kjsapitest_autogen/include/kjsapitest.moc:96:21
    #8 0x7f92783244fe in QMetaMethod::invoke(QObject*, Qt::ConnectionType, QGenericReturnArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) const /usr/src/debug/dev-qt/qtcore-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qmetaobject.cpp:2303:13
    #9 0x7f927841ed5c in QMetaMethod::invoke(QObject*, Qt::ConnectionType, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) const /usr/src/debug/dev-qt/qttest-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd_build/src/testlib/../../include/QtCore/../../../qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qmetaobject.h:122:16
    #10 0x7f927841ed5c in QTest::TestMethods::invokeTestOnData(int) const /usr/src/debug/dev-qt/qttest-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/testlib/qtestcase.cpp:938:41
    #11 0x7f927841f7d7 in QTest::TestMethods::invokeTest(int, char const*, QTest::WatchDog*) const /usr/src/debug/dev-qt/qttest-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/testlib/qtestcase.cpp:1166:17
    #12 0x7f9278420709 in QTest::TestMethods::invokeTests(QObject*) const /usr/src/debug/dev-qt/qttest-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/testlib/qtestcase.cpp:1507:33
    #13 0x7f9278420d54 in QTest::qRun() /usr/src/debug/dev-qt/qttest-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/testlib/qtestcase.cpp:1934:14
    #14 0x7f9278420a1d in QTest::qExec(QObject*, int, char**) /usr/src/debug/dev-qt/qttest-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/testlib/qtestcase.cpp:1842:15
    #15 0x23fdf3 in main /home/telans/src/kde/kjs/autotests/kjsapitest.cpp:283:1
    #16 0x7f92779967fc in __libc_start_main /usr/src/debug/sys-libs/glibc-2.33-r7/glibc-2.33/csu/../csu/libc-start.c:332:16
    #17 0x21af89 in _start /usr/src/debug/sys-libs/glibc-2.33-r7/glibc-2.33/csu/../sysdeps/x86_64/start.S:120

UndefinedBehaviorSanitizer can not provide additional info.
SUMMARY: UndefinedBehaviorSanitizer: SEGV /home/telans/src/kde/kjs/src/kjs/object.cpp:247:27 in KJS::JSObject::put(KJS::ExecState*, KJS::Identifier const&, KJS::JSValue*, int)
==2158002==ABORTING
Comment 11 James Beddek 2021-10-28 02:38:33 UTC
See below for where that Clang change introduced segfaults like mine, determined to be from UB.

https://reviews.llvm.org/D99790#2678384
Comment 12 Albert Astals Cid 2021-10-28 17:27:50 UTC
I can reproduce the problems with asan/ubsan, working on a path
Comment 13 Bug Janitor Service 2021-10-28 22:30:48 UTC
A possibly relevant merge request was started @ https://invent.kde.org/frameworks/kjs/-/merge_requests/5
Comment 14 Albert Astals Cid 2021-10-28 22:31:32 UTC
James you seem to know how to compile stuff, can you confirm that the patch in https://invent.kde.org/frameworks/kjs/-/merge_requests/5/diffs helps?
Comment 15 James Beddek 2021-10-29 01:45:02 UTC
Thanks for the patch! It fixes the kjs test as well as all the okular tests that were failing. Cheers
Comment 16 Albert Astals Cid 2021-11-25 23:29:29 UTC
Git commit fc93534ad433d5c5a41e0a4a1168253a0a0e69a6 by Albert Astals Cid.
Committed on 25/11/2021 at 23:28.
Pushed by aacid into branch 'master'.

Don't call functions on pointers that may not point to objects

The JSValue pointers sometimes are just a number (i.e. 3) so calling
functions on them is not allowed (and is starting to crash on latest
clang when compiled with optimization).

So always use a static function when the pointer may not be a real
pointer

M  +8    -8    autotests/ecmatest.cpp
M  +6    -6    src/kjs/ExecState.cpp
M  +2    -2    src/kjs/JSVariableObject.cpp
M  +4    -4    src/kjs/JSWrapperObject.cpp
M  +3    -3    src/kjs/api/kjsinterpreter.cpp
M  +12   -12   src/kjs/api/kjsobject.cpp
M  +18   -19   src/kjs/array_instance.cpp
M  +37   -37   src/kjs/array_object.cpp
M  +4    -4    src/kjs/bool_object.cpp
M  +49   -49   src/kjs/bytecode/codes.def
M  +2    -2    src/kjs/bytecode/machine.cpp.in
M  +1    -1    src/kjs/bytecode/opcodes.cpp.in
M  +2    -2    src/kjs/collector.cpp
M  +36   -36   src/kjs/date_object.cpp
M  +8    -8    src/kjs/error_object.cpp
M  +13   -13   src/kjs/function.cpp
M  +14   -14   src/kjs/function_object.cpp
M  +5    -5    src/kjs/internal.cpp
M  +1    -1    src/kjs/internal.h
M  +7    -7    src/kjs/interpreter.cpp
M  +8    -8    src/kjs/json_object.cpp
M  +19   -19   src/kjs/jsonstringify.cpp
M  +7    -7    src/kjs/kjs.cpp
M  +2    -2    src/kjs/list.cpp
M  +1    -1    src/kjs/lookup.h
M  +8    -8    src/kjs/math_object.cpp
M  +2    -2    src/kjs/nodes.cpp
M  +26   -26   src/kjs/number_object.cpp
M  +35   -35   src/kjs/object.cpp
M  +9    -4    src/kjs/object.h
M  +30   -30   src/kjs/object_object.cpp
M  +26   -26   src/kjs/operations.cpp
M  +4    -4    src/kjs/property_map.cpp
M  +11   -11   src/kjs/propertydescriptor.cpp
M  +17   -17   src/kjs/regexp_object.cpp
M  +48   -50   src/kjs/string_object.cpp
M  +41   -16   src/kjs/value.cpp
M  +289  -88   src/kjs/value.h
M  +3    -3    tests/testkjs.cpp

https://invent.kde.org/frameworks/kjs/commit/fc93534ad433d5c5a41e0a4a1168253a0a0e69a6