nsIStorageStream memory corruption when written into and read from nsIHttpChannel




6 years ago
a year ago


(Reporter: passfree, Unassigned)


13 Branch
Mac OS X

Firefox Tracking Flags

(Not tracked)


(Whiteboard: [necko-would-take])



6 years ago
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:12.0) Gecko/20100101 Firefox/12.0
Build ID: 20120420145725

Steps to reproduce:

I am writing a simple extension which creates a http channel and assigns a storage stream as an upload stream via the methods exposed by nsIUploadChannel interface. The browser will crash after data has been written into the storage stream output stream.

Actual results:

Here is an information about the crash:

0   libSystem.B.dylib                   0x00007fffffe00800 __memcpy + 96 
1   XUL                                 0x0000000100f58f98 NS_CopySegmentToBuffer(nsIInputStream*, void*, char const*, unsigned int, unsigned int, unsigned int*) + 40 (nsStreamUtils.cpp:760) 
2   XUL                                 0x0000000100f5af88 nsStorageInputStream::ReadSegments(unsigned int (*)(nsIInputStream*, void*, char const*, unsigned int, unsigned int, unsigned int*), void*, unsigned int, unsigned int*) + 248 (nsStorageStream.cpp:454) 
3   XUL                                 0x0000000100f55dcd nsMultiplexInputStream::Read(char*, unsigned int, unsigned int*) + 157 (nsMultiplexInputStream.cpp:224) 
4   XUL                                 0x0000000100f55dcd nsMultiplexInputStream::Read(char*, unsigned int, unsigned int*) + 157 (nsMultiplexInputStream.cpp:224) 
5   XUL                                 0x000000010004d526 nsBufferedInputStream::Fill() + 102 (nsBufferedStreams.cpp:426) 
6   XUL                                 0x000000010004cf59 nsBufferedInputStream::ReadSegments(unsigned int (*)(nsIInputStream*, void*, char const*, unsigned int, unsigned int, unsigned int*), void*, unsigned int, unsigned int*) + 217 (nsBufferedStreams.cpp:389) 
7   XUL                                 0x00000001000db97e nsHttpTransaction::ReadSegments(nsAHttpSegmentReader*, unsigned int, unsigned int*) + 142 (nsHttpTransaction.cpp:506) 
8   XUL                                 0x00000001000cd692 nsHttpConnection::OnSocketWritable() + 354 (nsHttpConnection.cpp:1097) 
9   XUL                                 0x00000001000cd770 nsHttpConnection::OnOutputStreamReady(nsIAsyncOutputStream*) + 16 (nsHttpConnection.cpp:1332) 
10  XUL                                 0x00000001000ccc66 nsHttpConnection::Activate(nsAHttpTransaction*, unsigned char, int) + 374 (nsHttpConnection.cpp:380) 
11  XUL                                 0x00000001000d19cd nsHttpConnectionMgr::DispatchTransaction(nsHttpConnectionMgr::nsConnectionE ntry*, nsHttpTransaction*, unsigned char, nsHttpConnection*) + 397 (nsHttpConnectionMgr.cpp:1284) 
12  XUL                                 0x00000001000d3096 nsHttpConnectionMgr::nsHalfOpenSocket::OnOutputStreamReady(nsIAsyncOutputSt ream*) + 1014 (nsHttpConnectionMgr.cpp:2210) 
13  XUL                                 0x000000010006ec6a nsSocketOutputStream::OnSocketReady(unsigned int) + 122 (nsCOMPtr.h:480) 
14  XUL                                 0x00000001000723ce nsSocketTransport::OnSocketReady(PRFileDesc*, short) + 398 (nsSocketTransport2.cpp:1568) 
15  XUL                                 0x0000000100074df7 nsSocketTransportService::DoPollIteration(bool) + 1095 (nsSocketTransportService2.cpp:762) 
16  XUL                                 0x000000010007505b nsSocketTransportService::Run() + 251 (nsSocketTransportService2.cpp:648) 
17  XUL                                 0x0000000100f6e317 nsThread::ProcessNextEvent(bool, bool*) + 407 (nsThread.cpp:657) 
18  XUL                                 0x000000010001de5a NS_ProcessNextEvent_P(nsIThread*, bool) + 26 (nsThreadUtils.cpp:245) 
19  XUL                                 0x0000000100f6e09d nsThread::ThreadFunc(void*) + 141 (nsThread.cpp:288) 
20  libnspr4.dylib                      0x0000000103694b4e _pt_root + 158 (ptthread.c:190) 
21  libSystem.B.dylib                   0x00007fff8964dfd6 _pthread_start + 331 
22  libSystem.B.dylib                   0x00007fff8964de89 thread_start + 13

I use something similar to this:

let PR_UINT32_MAX = Math.pow(2, 32) - 1; 
let storageStream = createInstance('...@mozilla.org/storagestream;1', 'nsIStorageStream'); 
storageStream.init(DEFAULT_SEGMENT_SIZE, PR_UINT32_MAX, null);
this.outputStream = streamTransportService.createOutputTransport(storageStream.getOutputStream( 0), -1, -1, true).openOutputStream(0, DEFAULT_SEGMENT_SIZE, DEFAULT_SEGMENT_COUNT).QueryInterface(CI.nsIAsyncOutputStream); 
request.upload(storageStream.newInputStream(0), forwarder);

The function request.upload does this:

let mimeInputStream = createInstance('@mozilla.org/network/mime-input-stream;1', 'nsIMIMEInputStream');
mimeInputStream.addContentLength = false;
this.channel.setUploadStream(mimeInputStream, '', -1);
this.channel.asyncOpen(streamListener, this);

Notice that this.outputStream is an asyn output stream which I pump data into every time it is available. The crash does not occur on first instance when write method is called but at later time. If I don't call write no crash will occur. Also, the crash wont occur immediately after or during a call to write.

Also, I have tested the rest of the code with a simple pipe implementation just to see if I am doing everything else correctly and it is working perfectly fine. Though, I need a storage stream because I want to allow other extension developers to be able to observe my requests and the data they carry. This is why I need a storage stream.
Is there any way you can write a complete JS-based test for this?  XPCShell testing should be able to show it.
Whiteboard: [necko-would-take]
You need to log in before you can comment on or make changes to this bug.