Prechádzať zdrojové kódy

LibJS: Fix UB downcast during GlobalObject construction

When constructing a GlobalObject, it has to pass itself as the global
object to its own Shape. Since this is done in the Object constructor,
and Object is a base class of GlobalObject, it's not yet valid to cast
"this" to a GlobalObject*.

Fix this by having Shape store the global object as an Object& and move
Shape::global_object() to GlobalObject.h where we can at least perform a
valid static_cast in the getter.

Found by oss-fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=29267
Andreas Kling 4 rokov pred
rodič
commit
fdd974b7ef

+ 5 - 0
Libraries/LibJS/Runtime/GlobalObject.h

@@ -125,4 +125,9 @@ inline void GlobalObject::add_constructor(const FlyString& property_name, Constr
     define_property(property_name, constructor, Attribute::Writable | Attribute::Configurable);
 }
 
+inline GlobalObject* Shape::global_object() const
+{
+    return static_cast<GlobalObject*>(m_global_object);
+}
+
 }

+ 1 - 1
Libraries/LibJS/Runtime/Object.cpp

@@ -90,7 +90,7 @@ Object* Object::create_empty(GlobalObject& global_object)
 Object::Object(GlobalObjectTag)
 {
     // This is the global object
-    m_shape = heap().allocate_without_global_object<Shape>(static_cast<GlobalObject&>(*this));
+    m_shape = heap().allocate_without_global_object<Shape>(*this);
 }
 
 Object::Object(ConstructWithoutPrototypeTag, GlobalObject& global_object)

+ 1 - 1
Libraries/LibJS/Runtime/Shape.cpp

@@ -72,7 +72,7 @@ Shape::Shape(ShapeWithoutGlobalObjectTag)
 {
 }
 
-Shape::Shape(GlobalObject& global_object)
+Shape::Shape(Object& global_object)
     : m_global_object(&global_object)
 {
 }

+ 3 - 3
Libraries/LibJS/Runtime/Shape.h

@@ -65,7 +65,7 @@ public:
     enum class ShapeWithoutGlobalObjectTag { Tag };
 
     explicit Shape(ShapeWithoutGlobalObjectTag);
-    explicit Shape(GlobalObject&);
+    explicit Shape(Object& global_object);
     Shape(Shape& previous_shape, const StringOrSymbol& property_name, PropertyAttributes attributes, TransitionType);
     Shape(Shape& previous_shape, Object* new_prototype);
 
@@ -78,7 +78,7 @@ public:
     bool is_unique() const { return m_unique; }
     Shape* create_unique_clone() const;
 
-    GlobalObject* global_object() const { return m_global_object; }
+    GlobalObject* global_object() const;
 
     Object* prototype() { return m_prototype; }
     const Object* prototype() const { return m_prototype; }
@@ -110,7 +110,7 @@ private:
     TransitionType m_transition_type : 6 { TransitionType::Invalid };
     bool m_unique : 1 { false };
 
-    GlobalObject* m_global_object { nullptr };
+    Object* m_global_object { nullptr };
 
     mutable OwnPtr<HashMap<StringOrSymbol, PropertyMetadata>> m_property_table;