Closed
Bug 304669
Opened 19 years ago
Closed 19 years ago
nsTimerImpl crashes even if called by JS, should me more defensive about pointers
Categories
(Core :: XPCOM, defect)
Core
XPCOM
Tracking
()
RESOLVED
FIXED
People
(Reporter: ma1, Assigned: ma1)
Details
(Keywords: crash)
Attachments
(1 file, 1 obsolete file)
|
1.61 KB,
patch
|
dougt
:
review+
dbaron
:
superreview+
|
Details | Diff | Splinter Review |
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8b4) Gecko/20050815
Firefox/1.0+
This JavaScript snippet crashes Firefox:
Components.classes["@mozilla.org/timer;1"]
.createInstance(Components.interfaces.nsITimer)
.initWithCallback(null,1000,0);
This is pretty obvious (in fact, I've noticed the problem looking at the source
code, rather than actually crashing my browser), because there's no argument
validation in nsTimerImpl::Init[WithXxx]() methods.
While it may be acceptable for InitFuncCallback(), which is meant to be called
by adult C++ programmers, it becomes embarrassing for scriptable methods like
InitWithCallback() and Init().
Also, we NS_RELEASE() the callback in ReleaseCallback(), but we give it away
through a public scriptable property. If a client (e.g. a poorly written plugin)
over-releases this property, we get another crash on next ReleaseCallback()
(e.g. in destructor). Maybe better replacing with NS_IF_RELEASE()?| Assignee | ||
Comment 1•19 years ago
|
||
Attachment #192712 -
Flags: superreview?(dbaron)
Attachment #192712 -
Flags: review?(timeless)
| Assignee | ||
Updated•19 years ago
|
Status: NEW → ASSIGNED
Comment on attachment 192712 [details] [diff] [review] Defensive callback management i'm not technically an xpcom peer, but yes i believe this should be accepted.
Attachment #192712 -
Flags: review?(timeless) → review?(dougt)
Comment 3•19 years ago
|
||
Comment on attachment 192712 [details] [diff] [review] Defensive callback management how can the mCallback.[i|o] be null? I think the .cpp change is good, but I do not understand the .h change.
| Assignee | ||
Comment 4•19 years ago
|
||
(In reply to comment #3) > (From update of attachment 192712 [details] [diff] [review] [edit]) > how can the mCallback.[i|o] be null? I think the .cpp change is good, but I do > not understand the .h change. Maybe you're right and this is overkill, but since I was ranting about defensive programming, I digged a bit of talkback data and found a ton of nsITimerImpl:ReleaseCallback() crap, e.g. http://talkback-public.mozilla.org/talkback/fastfind.jsp?search=2&type=iid&id=8360817 Being all but a XPCOM guru, I'm the last person who can tell you how it happens , but we both know shit do happen. OTHO, as a quite seasoned Java programmer, I can tell you it tends to happen in mysterious ways even in the safest environments, when threads are around, not to mention if a module is doomed by its own name :)
Maybe leave the NS_RELEASE's as-is, but add in NS_ASSERTION's to make sure that they're non-null? If the member is null, something pretty bad happened, I'd think, and we don't want to mask it..
I agree with dougt that the nsTimerImpl.h change should not be needed. It seems sensible to maintain the invariant that mCallbackType being set to non-UNKNOWN implies a non-null callback. Does your patch not cause us to maintain that invariant? If not, could you fix that instead?
| Assignee | ||
Comment 7•19 years ago
|
||
(In reply to comment #6) > I agree with dougt that the nsTimerImpl.h change should not be needed. It seems > sensible to maintain the invariant that mCallbackType being set to non-UNKNOWN > implies a non-null callback. Does your patch not cause us to maintain that > invariant? If not, could you fix that instead? My patch hardly change the extent that invariance is enforced to: as far as I can see nsITimerImpl already does its best on that front, unless some dark multithreading synchronization issue is happening (e.g. with the TimerManager destroying idle timers in concurrence with JS garbage collector), but I'm too much a newbie to tell. Actually, my .cpp patch prevents an early crash, happening as soon as the callback is reference counted ( NS_ADDREF(mCallback.[i|o]); ), so it's true that the forementioned invariance was screwed up, but the whole application was as well hence it didn't matter ;) Since there's actual talkback data telling that somehow we manage reach ReleaseCallback() with invalid pointers (and I tend to blame some external reference counting issue), I agree with vlad on the assertion thing in the .h patch, supposing he means "leave NS_IF_RELEASE() as it is" and add a *debug only* assertion to track bogus (client?) behaviours...
| Assignee | ||
Updated•19 years ago
|
Hardware: PC → All
Attachment #192712 -
Flags: superreview?(dbaron) → superreview-
| Assignee | ||
Comment 8•19 years ago
|
||
Cut down patch (.cpp only, no .h) per dbaron's sr- Probably the destructor crash do deserve a different bug and more investigation.
Attachment #192712 -
Attachment is obsolete: true
Attachment #192947 -
Flags: superreview?(dbaron)
Attachment #192947 -
Flags: review?(dougt)
Comment 9•19 years ago
|
||
Comment on attachment 192947 [details] [diff] [review] Argument validation only looks fine.
Attachment #192947 -
Flags: review?(dougt) → review+
Attachment #192947 -
Flags: superreview?(dbaron) → superreview+
Comment 10•19 years ago
|
||
Comment on attachment 192712 [details] [diff] [review] Defensive callback management clearing old flag
Attachment #192712 -
Flags: review?(dougt) → review-
Comment 12•19 years ago
|
||
Fixed on trunk.
Status: ASSIGNED → RESOLVED
Closed: 19 years ago
Resolution: --- → FIXED
You need to log in
before you can comment on or make changes to this bug.
Description
•