[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Trying to crack the Firefox crashing issue



chatgpt has opinions.

I put in my original run and backtrace from Nov 2023, and chatgpt had the following to say:

$ gdb firefox
GNU gdb (Debian 13.2-1) 13.2
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "powerpc64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from firefox...
Reading symbols from /usr/lib/debug/.build-id/4b/b6e1779513b3b7402680ba3c0652341bfc3155.debug...
(gdb) run
Starting program: /usr/bin/firefox

Thread 1 "firefox" received signal SIGSEGV, Segmentation fault.
i32_load8_u (addr=2014643200, mem=<optimized out>) at rlbox.wasm.c:146
146 rlbox.wasm.c: No such file or directory.
(gdb) bt
#0  i32_load8_u (addr=2014643200, mem=<optimized out>) at rlbox.wasm.c:146
#1  w2c_rlbox_streqci
    (var_p0=var_p0@entry=262000, var_p1=2014643200, instance=<optimized out>)
    at rlbox.wasm.c:774
#2  0x00007fffe9195c48 in w2c_rlbox_getEncodingIndex
    (var_p0=<optimized out>, instance=<optimized out>) at rlbox.wasm.c:66243
#3  w2c_rlbox_getEncodingIndex (var_p0=262000, instance=0x7fffd992c000)
    at rlbox.wasm.c:690
#4  w2c_rlbox_MOZ_XmlInitEncodingNS_0
    (instance=0x7fffd992c000, var_p0=438820, var_p1=438816, var_p2=262000)
    at rlbox.wasm.c:2316
#5  0x00007fffe91e305c in w2c_rlbox_initializeEncoding
    (instance=instance@entry=0x7fffd992c000, var_p0=var_p0@entry=438672)
    at rlbox.wasm.c:48270
#6  0x00007fffe92a77a8 in w2c_rlbox_prologInitProcessor
    (instance=0x7fffd992c000, var_p0=438672, var_p1=445856, var_p2=511392, var_p3=262140) at rlbox.wasm.c:45278
#7  0x00007fffe92b82e4 in w2c_rlbox_MOZ_XML_Parse_0
    (var_p3=0, var_p2=65536, var_p1=445856, var_p0=438672, instance=0x7fffd992c000) at rlbox.wasm.c:49293
#8  w2c_rlbox_MOZ_XML_Parse
    (instance=0x7fffd992c000, var_p0=438672, var_p1=445856, var_p2=65536, var_p3=0) at rlbox.wasm.c:20709
--Type <RET> for more, q to quit, c to continue without paging--
#9  0x00007fffea00fd50 in rlbox::rlbox_wasm2c_sandbox::impl_invoke_with_func_ptr<XML_Status (XML_ParserStruct*, char const*, int, int), XML_Status (unsigned int, unsigned int, int, int), unsigned int, unsigned int, unsigned int, bool>(XML_Status (*)(unsigned int, unsigned int, int, int), unsigned int&&, unsigned int&&, unsigned int&&, bool&&) (func_ptr=<optimized out>, this=0x7fffd992c000)
    at ./build-browser/dist/include/mozilla/rlbox/rlbox_wasm2c_sandbox.hpp:763
#10 rlbox::rlbox_sandbox<rlbox::rlbox_wasm2c_sandbox>::INTERNAL_invoke_with_func_ptr<XML_Status (XML_ParserStruct*, char const*, int, int), rlbox::tainted<XML_ParserStruct*, rlbox::rlbox_wasm2c_sandbox>&, rlbox::tainted<char const*, rlbox::rlbox_wasm2c_sandbox>, unsigned long, bool>(char const*, void*, rlbox::tainted<XML_ParserStruct*, rlbox::rlbox_wasm2c_sandbox>&, rlbox::tainted<char const*, rlbox::rlbox_wasm2c_sandbox>&&, unsigned long&&, bool&&) (func_name=<optimized out>, func_ptr=<optimized out>, this=<optimized out>)
    at ./build-browser/dist/include/mozilla/rlbox/rlbox_sandbox.hpp:790
#11 nsExpatDriver::ParseChunk(char16_t const*, unsigned int, nsExpatDriver::ChunkOrBufferIsFinal, unsigned int*, unsigned long*)
    (this=0x7ffff4856400, aBuffer=<optimized out>, aLength=aLength@entry=32768, aIsFinal=aIsFinal@entry=nsExpatDriver::ChunkOrBufferIsFinal::FinalChunk, aConsumed=0x7fffffffc50c, aLastLineLength=0x7fffffffc510) at ./parser/htmlparser/nsExpatDriver.cpp:1248
#12 0x00007fffea01015c in nsExpatDriver::ChunkAndParseBuffer(char16_t const*, unsigned int, bool, unsigned int*, unsigned int*, unsigned long*)
    (this=this@entry=0x7ffff4856400, aBuffer=aBuffer@entry=0x7fffd8f90020 u"<?xml version=\"1.0\"?>\n\n<!-- The \"global.css\" stylesheet is imported first to allow other stylesheets to\n     override rules using selectors with the same specificity. This applies to\n     both \"conten"..., aLength=aLength@entry=32768, aIsFinal=aIsFinal@entry=false, aPassedToExpat=aPassedToExpat@entry=0x7fffffffc508, aConsumed=aConsumed@entry=0x7fffffffc50c, aLastLineLength=aLastLineLength@entry=0x7fffffffc510) at ./parser/htmlparser/nsExpatDriver.cpp:1204
#13 0x00007fffea0105a0 in nsExpatDriver::ResumeParse(nsScanner&, bool)
    (this=0x7ffff4856400, aScanner=..., aIsFinalChunk=aIsFinalChunk@entry=false) at ./parser/htmlparser/nsExpatDriver.cpp:1352
#14 0x00007fffea016e3c in nsParser::ResumeParse(bool, bool, bool)
    (this=this@entry=0x7fffd99a2260, allowIteration=allowIteration@entry=true, aIsFinalChunk=aIsFinalChunk@entry=false, aCanInterrupt=aCanInterrupt@entry=true) at ./parser/htmlparser/nsParser.cpp:715
#15 0x00007fffea017d20 in nsParser::OnDataAvailable(nsIRequest*, nsIInputStream*, unsigned long, unsigned int)
    (sourceOffset=<optimized out>, aLength=<optimized out>, pIStream=<optimized out>, request=<optimized out>, this=0x7fffd99a2260)
    at ./parser/htmlparser/nsParser.cpp:1027
#16 nsParser::OnDataAvailable(nsIRequest*, nsIInputStream*, unsigned long, unsigned int)
    (this=0x7fffd99a2260, request=<optimized out>, pIStream=<optimized out>, sourceOffset=<optimized out>, aLength=<optimized out>)
    at ./parser/htmlparser/nsParser.cpp:978
#17 0x00007fffe9fd90a8 in .non-virtual thunk to mozilla::parser::PrototypeDocumentParser::OnDataAvailable(nsIRequest*, nsIInputStream*, unsigned long, unsigned int) () at ./parser/prototype/PrototypeDocumentParser.h:42
#18 0x00007fffe9f4bf30 in nsDocumentOpenInfo::OnDataAvailable(nsIRequest*, nsIInputStream*, unsigned long, unsigned int)
--Type <RET> for more, q to quit, c to continue without paging--c
    (this=<optimized out>, request=<optimized out>, inStr=<optimized out>, sourceOffset=<optimized out>, count=<optimized out>)
    at ./uriloader/base/nsURILoader.cpp:202
#19 0x00007fffe9c18610 in mozilla::net::ParentChannelWrapper::OnDataAvailable(nsIRequest*, nsIInputStream*, unsigned long, unsigned int)
    (this=<optimized out>, aRequest=<optimized out>, aInputStream=<optimized out>, aOffset=<optimized out>, aCount=<optimized out>)
    at ./netwerk/ipc/ParentChannelWrapper.h:27
#20 0x00007fffe9ab4550 in mozilla::net::ParentChannelListener::OnDataAvailable(nsIRequest*, nsIInputStream*, unsigned long, unsigned int)
    (this=0x7fffdfce9d00, aRequest=0x7ffff48b4dc0, aInputStream=0x7ffff73c93e0, aOffset=0, aCount=<optimized out>)
    at ./netwerk/protocol/http/ParentChannelListener.cpp:115
#21 0x00007fffe9f4bf30 in nsDocumentOpenInfo::OnDataAvailable(nsIRequest*, nsIInputStream*, unsigned long, unsigned int)
    (this=<optimized out>, request=<optimized out>, inStr=<optimized out>, sourceOffset=<optimized out>, count=<optimized out>)
    at ./uriloader/base/nsURILoader.cpp:202
#22 0x00007fffe9ed83d4 in nsJARChannel::OnDataAvailable(nsIRequest*, nsIInputStream*, unsigned long, unsigned int)
    (this=0x7ffff48b4dc0, req=<optimized out>, stream=0x7ffff73c93e0, offset=0, count=288947) at ./modules/libjar/nsJARChannel.cpp:1312
#23 0x00007fffe958f858 in nsInputStreamPump::OnStateTransfer() (this=this@entry=0x7ffff4852080) at ./netwerk/base/nsInputStreamPump.cpp:584
#24 0x00007fffe958fde8 in nsInputStreamPump::OnInputStreamReady(nsIAsyncInputStream*) (this=0x7ffff4852080, stream=<optimized out>)
    at ./netwerk/base/nsInputStreamPump.cpp:411
#25 0x00007fffe9377314 in CallbackHolder::CallbackHolder(nsIAsyncInputStream*, nsIInputStreamCallback*, unsigned int, nsIEventTarget*)::{lambda()#1}::operator()() const (__closure=<optimized out>) at ./xpcom/io/nsPipe3.cpp:73
#26 NS_NewCancelableRunnableFunction<CallbackHolder::CallbackHolder(nsIAsyncInputStream*, nsIInputStreamCallback*, unsigned int, nsIEventTarget*)::{lambda()#1}>(char const*, CallbackHolder::CallbackHolder(nsIAsyncInputStream*, nsIInputStreamCallback*, unsigned int, nsIEventTarget*)::{lambda()#1}&&)::FuncCancelableRunnable::Run() (this=<optimized out>) at ./build-browser/dist/include/nsThreadUtils.h:667
#27 NS_NewCancelableRunnableFunction<CallbackHolder::CallbackHolder(nsIAsyncInputStream*, nsIInputStreamCallback*, unsigned int, nsIEventTarget*)::{lambda()#1}>(char const*, CallbackHolder::CallbackHolder(nsIAsyncInputStream*, nsIInputStreamCallback*, unsigned int, nsIEventTarget*)::{lambda()#1}&&)::FuncCancelableRunnable::Run() (this=<optimized out>) at ./build-browser/dist/include/nsThreadUtils.h:665
#28 0x00007fffe93d8440 in mozilla::RunnableTask::Run() (this=0x7fffe6925000) at ./xpcom/threads/TaskController.cpp:559
#29 mozilla::TaskController::DoExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&)
    (this=this@entry=0x7ffff4841a00, aProofOfLock=...) at ./xpcom/threads/TaskController.cpp:886
#30 0x00007fffe93d9144 in mozilla::TaskController::ExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) (this=this@entry=0x7ffff4841a00, aProofOfLock=...) at ./xpcom/threads/TaskController.cpp:709
#31 0x00007fffe93d9614 in mozilla::TaskController::ProcessPendingMTTask(bool) (aMayWait=false, this=0x7ffff4841a00)
    at ./xpcom/threads/TaskController.cpp:495
#32 operator() (__closure=<optimized out>) at ./xpcom/threads/TaskController.cpp:218
#33 mozilla::detail::RunnableFunction<mozilla::TaskController::TaskController()::<lambda()> >::Run(void) (this=<optimized out>)
    at ./xpcom/threads/nsThreadUtils.h:548
#34 0x00007fffe93f284c in nsThread::ProcessNextEvent(bool, bool*) (this=0x7ffff48b0300, aMayWait=<optimized out>, aResult=0x7fffffffd1b7)
    at ./xpcom/threads/nsThread.cpp:1199
#35 0x00007fffe93f5954 in NS_ProcessNextEvent(nsIThread*, bool) (aThread=<optimized out>, aMayWait=<optimized out>)
    at ./xpcom/threads/nsThreadUtils.cpp:480
#36 0x00007fffe9d6736c in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) (this=0x7fffe8554700, aDelegate=0x7ffff7381c80)
    at ./ipc/glue/MessagePump.cpp:85
#37 0x00007fffe9d070e4 in MessageLoop::RunInternal() (this=<optimized out>) at ./build-browser/dist/include/mozilla/RefPtr.h:319
#38 MessageLoop::RunHandler() (this=<optimized out>) at ./ipc/chromium/src/base/message_loop.cc:363
#39 MessageLoop::Run() (this=<optimized out>) at ./ipc/chromium/src/base/message_loop.cc:345
#40 0x00007fffececdfa8 in nsBaseAppShell::Run() (this=0x7fffe85db780) at ./widget/nsBaseAppShell.cpp:148
#41 0x00007fffee34a918 in nsAppStartup::Run() (this=0x7fffe8584840) at ./build-browser/dist/include/nsCOMPtr.h:747
#42 0x00007fffee491114 in XREMain::XRE_mainRun() (this=this@entry=0x7fffffffd798) at ./toolkit/xre/nsAppRunner.cpp:5683
#43 0x00007fffee491fa8 in XREMain::XRE_main(int, char**, mozilla::BootstrapConfig const&)
    (this=this@entry=0x7fffffffd798, argc=argc@entry=1, argv=argv@entry=0x7fffffffefa8, aConfig=...) at ./toolkit/xre/nsAppRunner.cpp:5884
#44 0x00007fffee4927ec in XRE_main(int, char**, mozilla::BootstrapConfig const&) (argc=1, argv=0x7fffffffefa8, aConfig=...)
    at ./toolkit/xre/nsAppRunner.cpp:5940
#45 0x00007fffee4942cc in mozilla::BootstrapImpl::XRE_main(int, char**, mozilla::BootstrapConfig const&)
    (this=<optimized out>, argc=<optimized out>, argv=<optimized out>, aConfig=<optimized out>) at ./toolkit/xre/Bootstrap.cpp:45
#46 0x00000001000092b0 in do_main(int, char**, char**) (argc=<optimized out>, argv=<optimized out>, envp=envp@entry=0x7fffffffefb8)
    at ./browser/app/nsBrowserApp.cpp:227
#47 0x000000010000814c in main(int, char**, char**) (argc=<optimized out>, argv=<optimized out>, envp=0x7fffffffefb8)
    at ./browser/app/nsBrowserApp.cpp:445
(gdb)


==========================


The backtrace you've posted shows a **segmentation fault** (`SIGSEGV`) happening in Firefox when running under GDB on a PowerPC64 Linux system. The crash occurs in code generated by RLBox, specifically in `i32_load8_u` within `rlbox.wasm.c`, which appears to be part of a **WebAssembly sandboxed execution environment**. Here's a breakdown:

### Key Observations:

* **Faulting function**: `i32_load8_u (addr=2014643200)` — the address accessed is very large and likely invalid.
* **Sandbox**: RLBox is being used — this is a sandboxing framework to isolate parts of code, such as XML parsers or other libraries, via WebAssembly.
* **Fault path**:

  * `w2c_rlbox_getEncodingIndex` → `w2c_rlbox_MOZ_XmlInitEncodingNS_0` → `w2c_rlbox_prologInitProcessor` → eventually called via `nsExpatDriver::ParseChunk`
  * This indicates the crash is happening during XML parsing inside the sandbox, possibly parsing a stylesheet (`global.css` is mentioned in the XML).

### Possible Causes:

1. **Invalid pointer dereference** inside the sandbox — RLBox is trying to access memory at an address it shouldn't.
2. **Improper input data or parser state**, especially related to XML or encoding parsing.
3. **Compiler bug or undefined behavior** in sandboxed code generation.
4. **Architecture-specific issue** (PowerPC64) — most testing happens on x86/x86\_64, so bugs may surface on less common platforms.

### What You Can Do:

1. **Check if the address `2014643200` makes sense** in your sandbox — it's very high and likely an invalid offset into the RLBox memory.
2. **Enable RLBox debugging**:

   * Build Firefox with `--enable-debug` and set RLBox-related environment variables like:

     ```bash
     MOZ_RLBOX_SANDBOXED=1
     MOZ_RLBOX_VERBOSE=1
     ```
   * This might produce logs that indicate why the memory is invalid.
3. **Verify XML input**: Try to locate and examine the file or network resource being parsed — malformed or unexpected input could cause faults.
4. **Update Firefox**: Ensure you’re running the latest version of Firefox and all dependencies.
5. **File a bug**:

   * This may be a platform-specific bug. Mozilla tracks RLBox bugs [on Bugzilla](https://bugzilla.mozilla.org/). Include architecture (PowerPC64), the RLBox call path, and the faulty address.

Would you like help inspecting the specific value at `addr=2014643200` or guidance on how to reproduce the crash more minimally?
 

On Fri, May 9, 2025 at 6:45 AM Damien Stewart <hypexed@yahoo.com.au> wrote:
On 9/5/25 7:12 pm, Ed Robbins wrote:
Hello! Nice digging
Thanks!
On Fri, 9 May 2025 at 08:03, Damien Stewart <hypexed@yahoo.com.au> wrote:
The source:
static int FASTCALL
streqci(const char *s1, const char *s2) {
   for (;;) {
     char c1 = *s1++;
     char c2 = *s2++;
     if (ASCII_a <= c1 && c1 <= ASCII_z)
       c1 += ASCII_A - ASCII_a;
     if (ASCII_a <= c2 && c2 <= ASCII_z)
       /* The following line will never get executed.  streqci() is
        * only called from two places, both of which guarantee to put
        * upper-case strings into s2.
        */
       c2 += ASCII_A - ASCII_a; /* LCOV_EXCL_LINE */
     if (c1 != c2)
       return 0;
     if (! c1)
       break;
   }
   return 1;
}
I am not sure how rlbox sandboxing works, but looking at this code
from a cross platform perspective, I'd say the use of char is suspect,
because it may or may not be signed depending on platform, and then a
comparison is being performed on it. The first thing I'd do is change
it to:

unsigned char c1 = (unsigned char)*s1++;
unsigned char c2 = (unsigned char)*s2++;
It does assume 7-bit ASCII by the looks of it. Going by the rest of the code it only uses 7-bit strings. It's rather pedantic as it defines it's own ASCII character set rather than rely on C strings. :-)
I'd also remove FASTCALL because I don't know how that will behave
with rlbox or ppc in general.

According to this it should be blanked out on PPC/non-x86.

https://github.com/libexpat/libexpat/blob/master/expat/lib/internal.h

It might be a good idea to also check the rest of expat for similar issues too?

Good luck!
Ed

It might. It might be the entry down a rabbit hole as well. :-D


-- 
My regards,

Damien Stewart.

Reply to: