shithub: libmujs

Download patch

ref: edb50ad66f7601ca9a3544a0e9045e8a8c60561f
parent: bf4ac9420739b4ac3bc963bd2c7b69de36a8bb11
author: Tor Andersson <tor.andersson@artifex.com>
date: Mon Nov 7 07:52:05 EST 2022

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.

--- a/jsobject.c
+++ b/jsobject.c
@@ -134,25 +134,25 @@
 		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 @@
 	}
 	if (js_hasproperty(J, -1, "value")) {
 		hasvalue = 1;
-		js_setproperty(J, -3, name);
+		js_defproperty(J, -3, name, 0);
 	}
 
 	if (!writable) atts |= JS_READONLY;