dangling pointer usage in js_LookupPropertyWithFlags

VERIFIED INVALID

Status

()

Core
JavaScript Engine
--
major
VERIFIED INVALID
12 years ago
12 years ago

People

(Reporter: Mike Moening, Unassigned)

Tracking

Trunk
x86
Windows 2000
Points:
---

Firefox Tracking Flags

(Not tracked)

Details

(Reporter)

Description

12 years ago
When LookupPropertyWithFlags is run it calls js_StopResolving with a variable "entry" pointing to a freed chunk of memory.

Here's the line of code boundschecker is complaining about.
From my debugging it appears to be valid.

----------------------
    cleanup:
        js_StopResolving(cx, &key, JSRESFLAG_LOOKUP, entry, generation);
        if (!ok || *propp)
            return ok;
----------------------

Here's the contents of entry:
----------------------
-		entry	0x03b9c990 {hdr={...} key={...} flags=4261281277 }	JSResolvingEntry *
+		hdr	{keyHash=4261281277 }	JSDHashEntryHdr
-		key	{obj=0xfdfdfdfd id=-33686019 }	JSResolvingKey
+		obj	0xfdfdfdfd {map=??? slots=??? }	JSObject *
		id	-33686019	long
		flags	4261281277	unsigned long
---------------------

Current Call Stack:
---------------------------
>	js32d.dll!js_LookupPropertyWithFlags(JSContext * cx=0x03bb85b8, JSObject * obj=0x03ba5d38, long id=62859864, unsigned int flags=1, JSObject * * objp=0x078ea65c, JSProperty * * propp=0x078ea648)  Line 3238 + 0x30 bytes	C
 	js32d.dll!js_LookupProperty(JSContext * cx=0x03bb85b8, JSObject * obj=0x03ba5d38, long id=62859864, JSObject * * objp=0x078ea65c, JSProperty * * propp=0x078ea648)  Line 3085 + 0xb2 bytes	C
 	js32d.dll!call_enumerate(JSContext * cx=0x03bb85b8, JSObject * obj=0x03ba5d38)  Line 769 + 0x7f bytes	C
 	js32d.dll!js_PutCallObject(JSContext * cx=0x03bb85b8, JSStackFrame * fp=0x078f02bc)  Line 592 + 0x51 bytes	C
 	js32d.dll!js_Interpret(JSContext * cx=0x03bb85b8, unsigned char * pc=0x03bf49c0, long * result=0x078eed64)  Line 2412 + 0x51 bytes	C
 	js32d.dll!js_Execute(JSContext * cx=0x03bb85b8, JSObject * chain=0x03be9f48, JSScript * script=0x03c19170, JSStackFrame * down=0x00000000, unsigned int flags=0, long * result=0x078eef5c)  Line 1621 + 0x77 bytes	C
 	js32d.dll!JS_ExecuteScript(JSContext * cx=0x03bb85b8, JSObject * obj=0x03be9f48, JSScript * script=0x03c19170, long * rval=0x078eef5c)  Line 4262 + 0xa1 bytes	C



Deallocation Call Stack:
----------------------------
JS_DHashFreeTable	       jsdhash.c   94
ChangeTable	               jsdhash.c   524
@JS_DHashTableOperate@12       jsdhash.c   574
js_StartResolving              jscntxt.c   540
js_LookupPropertyWithFlags     jsobj.c	   3139
js_LookupProperty              jsobj.c	   3085
js_LookupHiddenProperty        jsobj.c	   2837
call_resolve                   jsfun.c	   824
js_LookupPropertyWithFlags     jsobj.c	   3180
js_LookupProperty              jsobj.c	   3085
call_enumerate                 jsfun.c	   769
js_PutCallObject               jsfun.c	   592
js_Interpret                   jsinterp.c  2412
js_Execute                     jsinterp.c  1621
JS_ExecuteScript               jsapi.c	   4262


Allocation Call Stack:
----------------------------
JS_DHashAllocTable                     jsdhash.c    88
JS_DHashTableInit                      jsdhash.c    250
JS_NewDHashTable                       jsdhash.c    200
js_StartResolving                      jscntxt.c    533
js_InitFunctionAndObjectClasses        jsapi.c      1172
JS_InitStandardClasses                 jsapi.c      1230



I'm having some strange problems with one of my scripts under heavy thread usage.
I think this *might* be the cause.
This is INVALID.  Boundschecker needs to wait till entry->foo is loaded before barking.  The generation number helps js_StopResolving know to revalidate entry in this case.

The current and deallocation stacks are on the same thread, and the deallocation stack is an extension of the current stack, right?  That's expected.  Again, the generation number saves the day here, by design, and no one loads memory pointed at by entry before js_StopResolving looks up entry again due to generation not matching the table's generation number.

/be
Status: NEW → RESOLVED
Last Resolved: 12 years ago
Resolution: --- → INVALID
(Reporter)

Comment 2

12 years ago
Brendan,

Why aren't those members underneath entry initialized? They look like garbage.
(In reply to comment #2)
> Brendan,
> 
> Why aren't those members underneath entry initialized? They look like garbage.

See comment 1 -- entry is pointing to free memory, but it's not used without a generation number match, which is guaranteed to mismatch when the table is reallocated.

/be
Status: RESOLVED → VERIFIED
(Reporter)

Comment 4

12 years ago
Thanks for the clarification!
You need to log in before you can comment on or make changes to this bug.