Bug 222452 - JSC Crash in makeString() while creating Error object.
Summary: JSC Crash in makeString() while creating Error object.
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Linux
: P2 Normal
Assignee: Keith Miller
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2021-02-25 19:11 PST by sunlili
Modified: 2021-03-09 15:30 PST (History)
12 users (show)

See Also:


Attachments
the test case causing a crash (104 bytes, text/javascript)
2021-02-25 19:11 PST, sunlili
no flags Details
MaybeNeedsTestRebaselines (2.74 KB, patch)
2021-03-09 12:07 PST, Keith Miller
no flags Details | Formatted Diff | Diff
Patch for landing (4.21 KB, patch)
2021-03-09 14:33 PST, Keith Miller
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description sunlili 2021-02-25 19:11:21 PST
Created attachment 421597 [details]
the test case causing a crash

Hello, following test case can cause a crash in the latest jsc.

bar_693 = '2.3023e-320';
foo_508 = bar_693.padEnd(2147483620, 1);
var newInstance = new foo_508(1, 2);

crash output:
Aborted (core dumped)

The JSC(WebKit-2.30.5) is compiled with static, debug option. 

We do some simple analysis for this crash. 'foo_508' is a large string. When 'foo_508' is used as a contructor, a TypeError should be thrown. However, during creating error message, 'foo_508' is evaluated in DerivedSources/ForwardingHeaders/wtf/text/StringConcatenate.h:makeString(). Since the foo_508's length is overflowed, a null string is returned and assigned to 'result' in makeString(), and causes the crash. I'm not sure this crash is a bug or a deliberate design.

ISec Lab.
2021.2.26
Comment 1 Alexey Proskuryakov 2021-02-26 09:43:03 PST
I don't think that we would call it entirely correct, but it is a long standing intentional behavior.


template<typename... StringTypes>
String makeString(StringTypes... strings)
{
    String result = tryMakeString(strings...);
    if (!result)
        CRASH();
    return result;
}
Comment 2 Darin Adler 2021-02-26 12:37:37 PST
The crash in makeString is 100% intentional.

The use of makeString rather than tryMakeString allows callers to select whether to crash or handle memory exhaustion differently. The full name of makeString is "makeString and crash if there is insufficient memory".

So the real question is about what invokes makeString and why.
Comment 3 Alexey Proskuryakov 2021-02-26 14:58:33 PST
Crash stack:

WTF::String WTF::makeString<WTF::String, char const*, WTF::String, char const*>(WTF::String, char const*, WTF::String, char const*) + 268

WTF::String WTF::makeString<WTF::String, char const*, WTF::String, char const*>(WTF::String, char const*, WTF::String, char const*) + 152

JSC::defaultSourceAppender(WTF::String const&, WTF::String const&, JSC::RuntimeType, JSC::ErrorInstance::SourceTextWhereErrorOccurred) + 128

JSC::ErrorInstance::finishCreation(JSC::VM&, JSC::JSGlobalObject*, WTF::String const&, WTF::String (*)(WTF::String const&, WTF::String const&, JSC::RuntimeType, JSC::ErrorInstance::SourceTextWhereErrorOccurred), JSC::RuntimeType, bool) + 1776

JSC::createTypeError(JSC::JSGlobalObject*, WTF::String const&, WTF::String (*)(WTF::String const&, WTF::String const&, JSC::RuntimeType, JSC::ErrorInstance::SourceTextWhereErrorOccurred), JSC::RuntimeType) + 192

JSC::createError(JSC::JSGlobalObject*, JSC::JSValue, WTF::String const&, WTF::String (*)(WTF::String const&, WTF::String const&, JSC::RuntimeType, JSC::ErrorInstance::SourceTextWhereErrorOccurred)) + 336
Comment 4 Darin Adler 2021-02-26 16:22:06 PST
Need one more level of backtrace so we can see who’s passing a long string to createError.
Comment 5 Darin Adler 2021-02-26 16:25:31 PST
I think the issue is that the error creation function is trying to get a description of the object, and ends up with the content of the string.
Comment 6 Radar WebKit Bug Importer 2021-03-04 15:08:56 PST
<rdar://problem/75059605>
Comment 7 Darin Adler 2021-03-04 15:19:47 PST
My take on our "architectural approach" to this: We should not pass an arbitrary, JavaScript-code-controlled, string to createError without doing some kind of length limit first.
Comment 8 Alexey Proskuryakov 2021-03-04 17:53:33 PST
Just to be clear, this is not be blocked on me or the reporter posting more information - this readily reproduces by pasting the test into the jsc tool on macOS.
Comment 9 Keith Miller 2021-03-09 12:07:23 PST
Created attachment 422739 [details]
MaybeNeedsTestRebaselines
Comment 10 Mark Lam 2021-03-09 13:22:42 PST
Comment on attachment 422739 [details]
MaybeNeedsTestRebaselines

r=me
Comment 11 Keith Miller 2021-03-09 14:32:15 PST
Talked to Darin in Slack and we settled on a 2KB max.
Comment 12 Keith Miller 2021-03-09 14:33:59 PST
Created attachment 422758 [details]
Patch for landing
Comment 13 EWS 2021-03-09 15:30:35 PST
Committed r274181: <https://commits.webkit.org/r274181>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 422758 [details].