From d4cca62bb47feabbc2306379f57a1f52b82d738b Mon Sep 17 00:00:00 2001
From: lawnjelly <lawnjelly@gmail.com>
Date: Sun, 22 Sep 2024 08:51:43 +0100
Subject: [PATCH] Fix physics platform behaviour regression

Lifetime checks for stored `RIDs` for collision objects assumed they had valid `object_ids`.
It turns out that some are not derived from `Object` and thus checking `ObjectDB` returns false for some valid `RIDs`.
To account for this we only perform lifetime checks on valid `object_ids`.
---
 scene/3d/physics_body.cpp | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index 456daa7a7d7a..6e2293c8411f 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -1083,7 +1083,12 @@ Vector3 KinematicBody::_move_and_slide_internal(const Vector3 &p_linear_velocity
 
 		// We need to check the on_floor_body still exists before accessing.
 		// A valid RID is no guarantee that the object has not been deleted.
-		if (ObjectDB::get_instance(on_floor_body_id)) {
+
+		// We can only perform the ObjectDB lifetime check on Object derived objects.
+		// Note that physics also creates RIDs for non-Object derived objects, these cannot
+		// be lifetime checked through ObjectDB, and therefore there is a still a vulnerability
+		// to dangling RIDs (access after free) in this scenario.
+		if (!on_floor_body_id || ObjectDB::get_instance(on_floor_body_id)) {
 			// This approach makes sure there is less delay between the actual body velocity and the one we saved.
 			bs = PhysicsServer::get_singleton()->body_get_direct_state(on_floor_body_rid);
 		}