-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
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
[3.x] Validate RIDs before freeing #55764
Conversation
71cb8d3
to
c58391c
Compare
@lawnjelly Can we get this reviewed? This is something that should be pushed into 3.5. |
Would need discussion with @reduz when he is available again I think (there are a number of ways of doing this, and I don't know offhand whether a NULL rid should generate an error, it could be used by e.g. dummy servers). |
Been a while, but looking at the logic, will the
This seems to be the same as
|
doc/classes/VisualServer.xml
Outdated
@@ -961,7 +961,19 @@ | |||
<return type="void" /> | |||
<argument index="0" name="rid" type="RID" /> | |||
<description> | |||
Tries to free an object in the VisualServer. | |||
Destroys an object created by the VisualServer. If the [RID] passed is not one created by the VisualServer, an error will be sent to the console. | |||
Note: After freeing the object, the RID now has a reference to invalid memory. It is not safe to free an invalid RID. Make sure to reset it before using it again by assigning it to `RID()`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: After freeing the object, the RID now has a reference to invalid memory. It is not safe to free an invalid RID. Make sure to reset it before using it again by assigning it to `RID()`. | |
[b]Note:[/b] After freeing the object, the RID now has a reference to invalid memory. It is not safe to free an invalid RID. Make sure to reset it before using it again by assigning it a new RID. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I specifically meant assigning it to RID()
as shown in the example shown in the xml.
eg.
VisualServer.free(myrid)
myrid = RID()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah but that's not portable syntax (won't work in C#), so I suggested the rephrasing to work it around. Isn't "a new RID" explicit enough? Also, wouldn't it work to assign a new valid RID from another object, if that's what the user wants?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But if you want to keep the explicit RID()
reference I don't mind. Just note the [b]
formatting around Note:
which should be added, we use it everywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assigning it to a new RID
to me suggests the meaning, "assigning it to another valid RID you have from another object, or creating a new RID (as part of a new object)". What we specifically want is to re-initialize the variable to a null or zero state.
The example shown is in GDScript. Aren't all document examples in gdscript? We could put in a C# version, but this would be the first time I've seen C# going into the manual. I guess the tutorials have both.
I've done the [b] formatting. I'll leave the RID()
until there is a better alternative.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm changing it to:
[b]Note:[/b] After freeing the object, the RID now has a reference to invalid memory. It is not safe to use or free an invalid RID. Before using the RID again, make sure to assign it to `RID()` or any other valid RID.
[codeblock]
...
This should also be changed in the new NavigationServer:
@reduz says:
So if @lawnjelly approves, I think this would be good to go (aside from my above review comments). Seems fairly safe either way, one difference for physics servers is that it will no longer run |
For the case of returning an error message from Maybe the author can run a headless server build just to test and confirm that this does not spam errors (as dummy servers can sometimes create and free NULL RIDs afaik). If it does spam errors with NULL RID, than maybe it could be changed to return with no error output, or have the output only in the builds where this might be relevant. |
It should spam errors if there are bugs in the engine that are causing the spam, so they can be identified in beta and rc builds and fixed. The lack of errors and validation is the reason the whole RID system has taken months of our time troubleshooting. It's still a poor system and we're just slapping bandaids on it. However this section of the PR is not about causing error spamming or not. It is about making the behavior between PhysicsServer, VisualServer, etc the same. Currently PS and VS behave differently. I brought VS inline with PS. The only question was if the opposite was desireable, PS inline with VS and silently fail.
I will try a server build. It appears that will build only on linux? |
Linux or macOS only yeah. |
In In |
Are you referring to _update_shapes() here? That will only be a problem if the end user of the server (typically another portion of the engine rather than a game dev) is abusing I noted that |
I built and ran the godot server. Am I supposed to have a project or something, or is this all you wanted to see, @lawnjelly ?
I also ran through --test string, math, oa_hash_map, etc. None of these produced any RID errors. I have pushed an update with the navserver update and doc changes. |
} else { | ||
ERR_FAIL_MSG("Invalid ID."); | ||
ERR_FAIL_MSG("Invalid RID."); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps if the message "Invalid RID" is now being used for a NULL RID with the first check, these messages at the end could be something like "RID not found."? 🤔
That might be handy to differentiate the two cases (although I doubt this later case will happen often).
To be honest I don't know much about the server builds. But what I have seen is that with dummy servers it can return NULL RIDs when you e.g. request a new e.g. sky. See https://github.com/godotengine/godot/blob/3.x/drivers/dummy/rasterizer_dummy.h for examples. So if we are using dummy servers that return NULL RIDs, we are relying on the client code checking they are valid before freeing, otherwise we will presumably get these error messages. But maybe we will not know whether this is a problem or not until merged and tried in various permutations. I guess as long as we have done as much testing as we can, it is ok to merge, although it might be an idea to change the two error messages as in my comment above to differentiate the two cases. 👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This went under the radar again, sorry for the delay. Giving it an approval so that we can properly keep track of it and merge.
It's a bit too late for 3.5 now as we're almost releasing 3.5-stable, but we can merge afterwards for 3.6 and consider a cherry-pick for 3.5.x if no regressions are noticed in 3.x
.
Thanks! |
Background
It is possible for a class to free objects in the visual server and physics servers that it doesn't own by sending RIDs with dangling pointers to VS::free(). It has been happening in C++ and should also be possible in GDscript and other languages. Refer to PR #54650 and issue #53374 .
Changes
Introduces a validity check for RIDs in VisualServer::free() and the three physics servers Bullet, SW, 2DSW, and NavigationServer, Navigation2DServer. However, this cannot protect against RIDs with dangling pointers by design of the RID system.
Adds a warning to the documentation for VisualServer, PhysicsServer, Physics2DServer, NavigationServer, and Navigation2DServer to alert users to clear their RIDs before reusing them.
Matches
VisualServer::free()
,NavigationServer::free()
behavior to that ofPhysics(2D)Server::free()
. When VS::free() receives an invalid RID, it now prints an error message to the console, as the Physics servers do.As a result of the third, the engine dumps 30-50 errors to the console complaining about invalid RIDs sent to VS::free(). These errors are fixed by #54650.@lawnjelly @RandomShaper