Closed
Bug 383426
Opened 18 years ago
Closed 18 years ago
document.normalize() crash in OOM situation
Categories
(Core :: DOM: Core & HTML, defect)
Tracking
()
RESOLVED
FIXED
People
(Reporter: jruderman, Assigned: jruderman)
Details
(Keywords: crash, testcase, Whiteboard: [sg:critical])
Attachments
(3 files, 3 obsolete files)
765 bytes,
text/html
|
Details | |
12.24 KB,
text/plain
|
Details | |
5.41 KB,
patch
|
Details | Diff | Splinter Review |
Steps to reproduce:
1. Load the testcase, preferably in a build that you're running from a terminal window.
2. Wait 20s for it to load.
3. Wait 100s for it to use 4G of virtual memory. (Watch it in Activity Monitor and/or watch for console output from malloc.)
4. Click the button.
Result: Crash in which pointers have been overwritten by bytes from UTF-16 text.
(gdb) bt
#0 0x45603003 in ?? ()
#1 0x18085ece in nsGenericElement::JoinTextNodes (this=0x410041, aFirst=0x410041, aSecond=0x410041) at /Users/jruderman/trunk/mozilla/content/base/src/nsGenericElement.cpp:1748
#2 0x00410041 in dyld_stub_fflush ()
Previous frame inner to this frame (corrupt stack?)
I hit this crash while trying to reproduce bug 374244.
Assignee | ||
Comment 1•18 years ago
|
||
I think the problem is that AppendASCIItoUTF16 doesn't check the return value of aDest.SetLength. The stack is intact just before the call to copy_string, but once that call finishes, the stack is corrupted.
http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/xpcom/string/src/nsReadableUtils.cpp&rev=1.68&mark=137,149#137
Assignee | ||
Updated•18 years ago
|
Whiteboard: [sg:critical]
Assignee | ||
Comment 2•18 years ago
|
||
This fixes the crash during normalize() for me. I get a crash later (in layout rather than DOM), due to the "new" operator thinking it should throw rather than return null, but that's much better than a corrupted stack :)
If this is the right approach, I can write a patch that does the same thing to all the "Append" functions in nsReadableUtils.cpp.
Comment 3•18 years ago
|
||
You could use GetMutableData (see also bug 335957).
Updated•18 years ago
|
Flags: blocking1.9?
Assignee | ||
Comment 4•18 years ago
|
||
The GetMutableData interface confuses me. Does the fact that it returns a length rather than a pointer mean I'm supposed to check that the returned length is correct? If newLen is 0, how am I supposed to use the return value?
Comment 5•18 years ago
|
||
Can't you just return if the length you want is bigger than what GetMutableData returns? That should be able to deal with 0.
Assignee: nobody → jruderman
Flags: blocking1.9? → blocking1.9+
Jesse, are you going to revise your patch or do you want me to take it over?
Assignee | ||
Comment 7•18 years ago
|
||
I can revise it in a few days, but it would be great if you'd take it over.
Assignee | ||
Comment 8•18 years ago
|
||
Like this?
This patch has the same effect for me as the last one (no crash during normalize(), safe crash much later).
Attachment #267394 -
Attachment is obsolete: true
That looks good to me, although I'd fuse these into one statement:
+ PRUint32 actual_new_dest_length;
+
+ actual_new_dest_length = aDest.GetMutableData(&dummy, new_dest_length);
Assignee | ||
Comment 10•18 years ago
|
||
Ok. I initially had those as separate lines to avoid an 85-character line, but now I see that 90-character lines are not unusual in this file.
Please tick to 80 columns, but you could do:
PRUint32 actual_new_dest_length
= aDest.GetMutableData(&dummy, new_dest_length);
Assignee | ||
Comment 12•18 years ago
|
||
Should I make a patch that does the same thing to all the Append conversion functions?
That sounds like a great idea.
Assignee | ||
Comment 14•18 years ago
|
||
This introduces a "SetLengthForWriting" function so I don't have to include a bunch of redundant code in each Append* function.
Attachment #268603 -
Attachment is obsolete: true
Attachment #268904 -
Flags: superreview?(roc)
Attachment #268904 -
Flags: review?(peterv)
Comment on attachment 268904 [details] [diff] [review]
patch to fix all uses of SetLength in nsReadableUtils.cpp
+bool
PRBool
+ if (!SetLengthForWritingC(aDest, old_dest_length + aSource.Length()))
+ {
+ return;
+ }
Better to just write:
+ if (!SetLengthForWritingC(aDest, old_dest_length + aSource.Length()))
+ return;
Attachment #268904 -
Flags: superreview?(roc) → superreview+
Comment 16•18 years ago
|
||
Comment on attachment 268904 [details] [diff] [review]
patch to fix all uses of SetLength in nsReadableUtils.cpp
Ideally we'd also use the pointer returned by GetMutableData instead of using iterators, but let's just fix the crash first.
Attachment #268904 -
Flags: review?(peterv) → review+
Assignee | ||
Comment 17•18 years ago
|
||
Attachment #268904 -
Attachment is obsolete: true
Assignee | ||
Comment 18•18 years ago
|
||
Fixed on trunk. This testcase is way too slow for an automated test. Using ulimit (Linux only?) could make it faster, or maybe we could make a C++ test file that uses the string classes directly.
Status: NEW → RESOLVED
Closed: 18 years ago
Flags: in-testsuite?
Resolution: --- → FIXED
Assignee | ||
Comment 19•17 years ago
|
||
Loading the testcase and waiting 10 minutes makes my branch build abort:
firefox-bin(5906,0xa000d000) malloc: *** vm_allocate(size=33558528) failed (error code=3)
firefox-bin(5906,0xa000d000) malloc: *** error: can't allocate region
firefox-bin(5906,0xa000d000) malloc: *** set a breakpoint in szone_error to debug
terminate called after throwing an instance of 'std::bad_alloc'
what(): St9bad_alloc
That makes it hard to use the testcase to determine whether branch has the memory safety bug, since I don't get a chance to click the normalize button.
Updated•12 years ago
|
Group: core-security
Updated•6 years ago
|
Component: DOM → DOM: Core & HTML
You need to log in
before you can comment on or make changes to this bug.
Description
•