-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Use RegDeleteTree in RegistryKey.DeleteSubKeyTree #82598
Conversation
Tagging subscribers to this area: @dotnet/area-microsoft-win32 Issue DetailsFixes #82586
|
cc @stephentoub @danmoseley FYI |
I'm guessing this was simply because the API only appeared in Vista and this was written before then? |
} | ||
} | ||
} | ||
int ret = Interop.Advapi32.RegDeleteTree(_hkey, subkey); |
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.
Doc says:
A handle to an open registry key. The key must have been opened with the following access rights: DELETE, KEY_ENUMERATE_SUB_KEYS, and KEY_QUERY_VALUE. For more information, see Registry Key Security and Access Rights.
but for RegDeleteKeyEx it does not require this
A handle to an open registry key. The access rights of this key do not affect the delete operation. For more information about access rights, see Registry Key Security and Access Rights.
Is there any way this change could cause something to fail that worked before?
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 don't think it can cause deletion to fail. Should we add a manual access check to restore existing behavior?
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.
you mean, you've verified that all codepaths that lead here provide a handle that has DELETE, KEY_ENUMERATE_SUB_KEYS, and KEY_QUERY_VALUE?
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 is a public API. I mean that we may perform additional access check to match the document.
I've checked Windows source code and RegDeleteKeyEx
uses the same enumeration process. I'm not sure where the access check happens though.
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.
Maybe you can try to answer this question through testing. Is there a case where you can specify different values of RegistryRights when opening the key and see if you can create a situation where it would pass before but fails now?
I tend to agree with you that the old case should have needed these permissions - should be pretty easy to test to prove that.
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 we need a matrix for behaviors of the old and new way. The old way should also cause partial deletion in some 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.
Notes after reading more about registry:
- The
RegistryKeyPermissionCheck
orisWritable
check only happens at managed side. It can be easily replicated. - Registry checks the access of current user, not desired access of the handle.
So special casing "" should be enough. No matrix needed actually.
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.
The following code fails to delete with P/Invoke, but successes with DeleteSubKeyTree on .NET 7:
I can't reproduce the failure now. Maybe I missed something.
Edit: RegDeleteTree returns ACCESS_DENIED when lpSubKey is "" and the key contains values.
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 think the key thing here is to have tests that pass on both the old and new ways, if we don't already, to prove there's no visible change in behavior. There are no doubt snippets of code elsewhere in the tests that you can grab to set ACL's on keys, etc.
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.
The failures should be the documented case of RegDeleteTree
:
If the key has values, it must be opened with KEY_SET_VALUE or this function will fail with ERROR_ACCESS_DENIED.
I think covering the case should be enough. ACL handlings shouldn't be changed.
19850c7
to
1404726
Compare
@huoyaoyuan can you please add tests that protects the new behavior and assert that scenarios that should fail, do fail (above conversation)? |
Sure, I'll also decide the matrix to test when I'm available. |
I think it's ready now. @danmoseley should we bring this into 8.0? How about the risk? |
That's up to the area owner but I see no particular reason to port it. |
If it gets merged into main before main forks for .NET 9 (which has not yet happened), then it'll be in .NET 8. If it misses that cut-off, it'd be in .NET 9. |
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.
Thank you a lot for the contribution. As you restored the previous behavior around key self-deletion and you added tests for it, I think the change is ready. Merging.
Fixes #82586