Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Resource Importer use after free #84872

Merged
merged 1 commit into from
Nov 14, 2023

Conversation

alesliehughes
Copy link
Contributor

Coverity reported issue.

If scene is a ImporterMeshInstance3D, it will be recreated which will leave the pointer (scene) in a bad state.

Testing with a single blend file, it appear not be this scenario. Only the child items appeared to be updated, so I'm not sure if this is the normal case for all import files.

These raise the questions

  1. Will the first level scene ever be an ImporterMeshInstance3D object?
  2. Does anyone have an example that would have ImporterMeshInstance3D as the scene. Or instructions to do it

Found code just down from my change,

err = OK;"
...
if (!scene) {
		 EditorNode::add_io_error(
				TTR("Error running post-import script:") + " " + post_import_script_path + "\n" +
				TTR("Did you return a Node-derived object in the `_post_import()` method?"));
		return err;
	}

Should this be returning an error of some sort?

@alesliehughes alesliehughes requested a review from a team as a code owner November 14, 2023 05:54
@akien-mga
Copy link
Member

I'm not familiar with this code, but the proposed solution seems unconventional. Both returning the pointer while keeping modifying it passed as argument in recursive calls seems like a recipe for disaster, or at least not knowing what one ends up with when reading that code.

@alesliehughes
Copy link
Contributor Author

Sure. That makes sense. I'll give it another go.

Was just looking for some feedback as the right direction to take.

@fire
Copy link
Member

fire commented Nov 14, 2023

@lyuma You may be interested in looking at this.

@lyuma
Copy link
Contributor

lyuma commented Nov 14, 2023

Reproduction steps.

  1. Make a new "MeshInstance3D" scene (or use "Convert To" on the root node to make it MeshInstance3D.
  2. Export the glTF in Godot 4.2: Due to GLTF: Add root node export options and GODOT_single_root extension #81851 being merged and Add export settings to the export dialog for GLTF #79316 not being merged, export now always forces the GODOT_single_root extension which tells the importer to exclude the root node.
  3. Godot will crash immediately after export due to the root node being an ImporterMeshInstance3D (this issue).

Reproduction glb model (rename to .glb)
CubeExported.glb.cpuprofile

Copy link
Member

@aaronfranke aaronfranke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I investigated the code without looking at this PR, and I ended up coming to the same conclusion as the OP. We need to return a pointer to the new node, because we are replacing the node. This PR is exactly what I'd do to fix the problem.

@akien-mga: Both returning the pointer while keeping modifying it passed as argument in recursive calls seems like a recipe for disaster, or at least not knowing what one ends up with when reading that code.

Well, it's not passed in recursive calls. The recursive calls have p_node set to the previous call's p_node->get_child(i). Which are the same children as the original p_node's children, because we are using replace_by.

Once we run replace_by, we are freeing the old node, so there is no purpose to having a reference to the old p_node, so it makes perfect sense to me to overwrite that.

@akien-mga akien-mga modified the milestones: 4.x, 4.2 Nov 14, 2023
@akien-mga akien-mga merged commit 6197f09 into godotengine:master Nov 14, 2023
15 checks passed
@akien-mga
Copy link
Member

Thanks!

@alesliehughes alesliehughes deleted the res_import_scene branch November 14, 2023 22:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants