Fix RangeRetriever memory leak in IsMemberOfInStore method #121042
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Fixes a memory leak in
ADStoreCtx.IsMemberOfInStore()where aRangeRetrieverobject was not being disposed in all code paths, as reported in issue #<issue_number>.Problem
The
RangeRetrieverclass implementsIDisposablebut was not being properly disposed in theIsMemberOfInStoremethod. Specifically:RangeRetrieverwas never disposed if the method returned early after finding a match (line 1782)cachedMembersEnumfor later usedsanddefaultNCDirEntry, leaving theRangeRetrieverto leakUnder heavy load or repeated calls, this could lead to resource exhaustion and memory pressure.
Solution
Added proper disposal tracking and cleanup:
rangeRetrieverToDisposevariable to track theRangeRetrieverinstanceAll disposal calls use an explicit cast to
IDisposablesince theDispose()method is explicitly implemented asvoid IDisposable.Dispose().Testing
IsMemberOfandMembers.Containscode pathsNotes
This is a minimal, surgical fix that only adds 5 lines of code to ensure proper resource cleanup without changing any behavior or public APIs.
Original prompt
This section details on the original issue you should resolve
<issue_title>new RangeRetriever(groupDE, "member", false) is not disposed at the end of the function</issue_title>
<issue_description>### Description
dotnet 6.0
File: /src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/ADStoreCtx.cs:1795
Problem: new RangeRetriever(groupDE, "member", false) is not disposed at the end of the function
Reproduction Steps
Role: detected
detected
[ADStoreCtx.cs:[1795:0]](
Role: tracepoint
2.1 Step 1: Condition g.fakePrincipal taking any branch
[ADStoreCtx.cs:[1750:17]]
2.2 Step 2: Condition p.ContextType != ContextType.Domain taking any branch
[ADStoreCtx.cs:[1757:17]]
2.3 Step 3: Condition g.UnderlyingObject != null taking any branch
[ADStoreCtx.cs:[1763:26]]
2.4 Step 4: Condition p.fakePrincipal taking any branch
[ADStoreCtx.cs:[1768:18]]
2.5 Step 5: Condition Sid == null taking false branch
[ADStoreCtx.cs:[1817:17]]
2.6 Step 6: Condition string.IsNullOrEmpty(this.UserSuppliedServerName) taking any branch
[ADStoreCtx.cs:[1827:42]]
2.7 Step 7: Condition stringSid == null taking false branch
[ADStoreCtx.cs:[1838:21]]
2.8 Step 8: Condition sr == null taking any branch
[ADStoreCtx.cs:[1855:21]]
no escape
[ADStoreCtx.cs:[1861:45]]
2.9 Step 9: Exiting the foreach
[ADStoreCtx.cs:[1861:45]]
2.10 Step 10: Condition cachedMembersEnum is null taking any branch
[ADStoreCtx.cs:[1861:45]]
2.11 Step 11: Condition ds != null taking any branch
[ADStoreCtx.cs:[1876:21]]
2.12 Step 12: Condition defaultNCDirEntry != null taking any branch
[ADStoreCtx.cs:[1880:21]]
Expected behavior
memory leak
Actual behavior
same
Regression?
No response
Known Workarounds
No response
Configuration
No response
Other information
Found by Linux Verification Center (linuxtesting.org) with SVACE.</issue_description>
Comments on the Issue (you are @copilot in this section)
@ Tagging subscribers to this area: @dotnet/area-system-directoryservices, @jay98014 See info in [area-owners.md](https://github.com/dotnet/runtime/blob/main/docs/area-owners.md) if you want to be subscribed.Issue Details
Description
dotnet 6.0
File: /src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/ADStoreCtx.cs:1795
Problem: new RangeRetriever(groupDE, "member", false) is not disposed at the end of the function
Reproduction Steps
Role: detected
detected
[ADStoreCtx.cs:[1795:0]](
Role: tracepoint
2.1 Step 1: Condition g.fakePrincipal taking any branch
[ADStoreCtx.cs:[1750:17]]
2.2 Step 2: Condition p.ContextType != ContextType.Domain taking any branch
[ADStoreCtx.cs:[1757:17]]
2.3 Step 3: Condition g.UnderlyingObject != null taking any branch
[ADStoreCtx.cs:[1763:26]]
2.4 Step 4: Condition p.fakePrincipal taking any branch
[ADStoreCtx.cs:[1768:18]]
2.5 Step 5: Condition Sid == null taking false branch
[ADStoreCtx.cs:[1817:17]]
2.6 Step 6: Condition string.IsNullOrEmpty(this.UserSuppliedServerName) taking any branch
[ADStoreCtx.cs:[1827:42]]
2.7 Step 7: Condition stringSid == null taking false branch
[ADStoreCtx.cs:[1838:21]]
2.8 Step 8: Condition sr == null taking any branch
[ADStoreCtx.cs:[1855:21]]
no escape
[ADStoreCtx.cs:[1861:45]]
2.9 Step 9: Exiting the foreach
[ADStoreCtx.cs:[1861:45]]
2.10 Step 10: Condition cachedMembersEnum is null taking any branch
[ADStoreCtx.cs:[1861:45]]
2.11 Step 11: Condition ds != null taking any branch
[ADStoreCtx.cs:[1876:21]]
2.12 Step 12: Condition defaultNCDirEntry != null taking any branch
[ADStoreCtx.cs:[1880:21]]
Expected behavior
memory leak
Actual behavior
same
Regression?
No response
Known Workarounds
No response
Configuration
No response
Other information
Found by Linux Verification Center (linuxtesting.org) with SVACE.
area-System.DirectoryServices,untriagedFixes #94755
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.