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

Use RegDeleteTree in RegistryKey.DeleteSubKeyTree #82598

Merged
merged 5 commits into from
Jul 21, 2023

Conversation

huoyaoyuan
Copy link
Member

Fixes #82586

@ghost ghost added the community-contribution Indicates that the PR has been added by a community member label Feb 24, 2023
@ghost
Copy link

ghost commented Feb 24, 2023

Tagging subscribers to this area: @dotnet/area-microsoft-win32
See info in area-owners.md if you want to be subscribed.

Issue Details

Fixes #82586

Author: huoyaoyuan
Assignees: -
Labels:

area-Microsoft.Win32, community-contribution

Milestone: -

@carlossanlop
Copy link
Member

cc @stephentoub @danmoseley FYI

@danmoseley
Copy link
Member

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);
Copy link
Member

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?

Copy link
Member Author

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?

Copy link
Member

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?

Copy link
Member Author

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.

Copy link
Member

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.

Copy link
Member Author

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.

Copy link
Member Author

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 or isWritable 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.

Copy link
Member Author

@huoyaoyuan huoyaoyuan Jul 9, 2023

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.

Copy link
Member

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.

Copy link
Member Author

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.

@ViktorHofer
Copy link
Member

@huoyaoyuan can you please add tests that protects the new behavior and assert that scenarios that should fail, do fail (above conversation)?

@ViktorHofer ViktorHofer added the needs-author-action An issue or pull request that requires more info or actions from the author. label Jun 26, 2023
@huoyaoyuan
Copy link
Member Author

Sure, I'll also decide the matrix to test when I'm available.

@ghost ghost removed the needs-author-action An issue or pull request that requires more info or actions from the author. label Jun 26, 2023
@huoyaoyuan
Copy link
Member Author

I think it's ready now. @danmoseley should we bring this into 8.0? How about the risk?

@danmoseley
Copy link
Member

That's up to the area owner but I see no particular reason to port it.

@stephentoub
Copy link
Member

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.

Copy link
Member

@ViktorHofer ViktorHofer left a 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.

@ViktorHofer ViktorHofer merged commit 03acd23 into dotnet:main Jul 21, 2023
@huoyaoyuan huoyaoyuan deleted the reg-delete-tree branch July 21, 2023 11:15
@ghost ghost locked as resolved and limited conversation to collaborators Aug 20, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-Microsoft.Win32 community-contribution Indicates that the PR has been added by a community member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Microsoft.Win32.RegistryKey.DeleteSubKeyTree can use RegDeleteTreeW
7 participants