mirror of
https://github.com/ccxvii/mujs.git
synced 2026-02-06 01:41:37 +08:00
Bug 706057: Fix use-after-free in getOwnPropertyDescriptor.
getOwnPropertyDescriptor should create the descriptor object by using [[DefineOwnProperty]], and not by looking through the prototype chain where it may invoke getters and setters on the Object.prototype. If there exists an Object.prototype.get property with a setter, that method is invoked when it shouldn't. A malicious getter here can delete the property currently being processed in getOwnPropertyDescriptor, and we'll end up with a use-after-free bug. Avoid this problem by following the spec and use js_defproperty rather than js_setproperty to define own properties in getOwnPropertyDescriptor and related functions.
This commit is contained in:
14
jsobject.c
14
jsobject.c
@@ -134,25 +134,25 @@ static void O_getOwnPropertyDescriptor(js_State *J)
|
|||||||
js_newobject(J);
|
js_newobject(J);
|
||||||
if (!ref->getter && !ref->setter) {
|
if (!ref->getter && !ref->setter) {
|
||||||
js_pushvalue(J, ref->value);
|
js_pushvalue(J, ref->value);
|
||||||
js_setproperty(J, -2, "value");
|
js_defproperty(J, -2, "value", 0);
|
||||||
js_pushboolean(J, !(ref->atts & JS_READONLY));
|
js_pushboolean(J, !(ref->atts & JS_READONLY));
|
||||||
js_setproperty(J, -2, "writable");
|
js_defproperty(J, -2, "writable", 0);
|
||||||
} else {
|
} else {
|
||||||
if (ref->getter)
|
if (ref->getter)
|
||||||
js_pushobject(J, ref->getter);
|
js_pushobject(J, ref->getter);
|
||||||
else
|
else
|
||||||
js_pushundefined(J);
|
js_pushundefined(J);
|
||||||
js_setproperty(J, -2, "get");
|
js_defproperty(J, -2, "get", 0);
|
||||||
if (ref->setter)
|
if (ref->setter)
|
||||||
js_pushobject(J, ref->setter);
|
js_pushobject(J, ref->setter);
|
||||||
else
|
else
|
||||||
js_pushundefined(J);
|
js_pushundefined(J);
|
||||||
js_setproperty(J, -2, "set");
|
js_defproperty(J, -2, "set", 0);
|
||||||
}
|
}
|
||||||
js_pushboolean(J, !(ref->atts & JS_DONTENUM));
|
js_pushboolean(J, !(ref->atts & JS_DONTENUM));
|
||||||
js_setproperty(J, -2, "enumerable");
|
js_defproperty(J, -2, "enumerable", 0);
|
||||||
js_pushboolean(J, !(ref->atts & JS_DONTCONF));
|
js_pushboolean(J, !(ref->atts & JS_DONTCONF));
|
||||||
js_setproperty(J, -2, "configurable");
|
js_defproperty(J, -2, "configurable", 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,7 +248,7 @@ static void ToPropertyDescriptor(js_State *J, js_Object *obj, const char *name,
|
|||||||
}
|
}
|
||||||
if (js_hasproperty(J, -1, "value")) {
|
if (js_hasproperty(J, -1, "value")) {
|
||||||
hasvalue = 1;
|
hasvalue = 1;
|
||||||
js_setproperty(J, -3, name);
|
js_defproperty(J, -3, name, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!writable) atts |= JS_READONLY;
|
if (!writable) atts |= JS_READONLY;
|
||||||
|
|||||||
Reference in New Issue
Block a user