From edb50ad66f7601ca9a3544a0e9045e8a8c60561f Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Mon, 7 Nov 2022 12:52:05 +0100 Subject: [PATCH] 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. --- jsobject.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/jsobject.c b/jsobject.c index 78ea344..a58fc3a 100644 --- a/jsobject.c +++ b/jsobject.c @@ -134,25 +134,25 @@ static void O_getOwnPropertyDescriptor(js_State *J) js_newobject(J); if (!ref->getter && !ref->setter) { js_pushvalue(J, ref->value); - js_setproperty(J, -2, "value"); + js_defproperty(J, -2, "value", 0); js_pushboolean(J, !(ref->atts & JS_READONLY)); - js_setproperty(J, -2, "writable"); + js_defproperty(J, -2, "writable", 0); } else { if (ref->getter) js_pushobject(J, ref->getter); else js_pushundefined(J); - js_setproperty(J, -2, "get"); + js_defproperty(J, -2, "get", 0); if (ref->setter) js_pushobject(J, ref->setter); else js_pushundefined(J); - js_setproperty(J, -2, "set"); + js_defproperty(J, -2, "set", 0); } 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_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")) { hasvalue = 1; - js_setproperty(J, -3, name); + js_defproperty(J, -3, name, 0); } if (!writable) atts |= JS_READONLY; -- 2.20.1