Skip to content

fix: WQL escaping, atomic lock operations, safe CTS disposal (CQ-007, CQ-008, CQ-015)#374

Merged
laurentiu021 merged 1 commit into
mainfrom
fix/medium-cq-batch-2
May 15, 2026
Merged

fix: WQL escaping, atomic lock operations, safe CTS disposal (CQ-007, CQ-008, CQ-015)#374
laurentiu021 merged 1 commit into
mainfrom
fix/medium-cq-batch-2

Conversation

@laurentiu021

@laurentiu021 laurentiu021 commented May 15, 2026

Copy link
Copy Markdown
Owner

Summary

Addresses 3 MEDIUM findings from QA audit.

Changes

CQ-007: DiskHealthService WQL injection (MEDIUM)

  • Added single-quote escaping to WQL ASSOCIATORS OF query objectId
  • Prevents potential WQL injection if disk ObjectId contains quotes

CQ-008: OperationLockService redundant lock (MEDIUM)

  • Removed lock object; TryAcquire uses atomic ConcurrentDictionary.TryAdd
  • Release uses atomic TryRemove
  • Eliminates unnecessary contention while maintaining thread safety

CQ-015: PingMonitorService CTS race (MEDIUM)

  • CTS now only disposed if background loop task IsCompleted
  • Prevents ObjectDisposedException when pump doesn't exit within 1.5s timeout

Build

  • 0 errors (main + tests)

Summary by CodeRabbit

  • Bug Fixes
    • Fixed WQL injection vulnerability in disk health monitoring
    • Improved concurrent operation handling for enhanced stability
    • Resolved resource disposal issue in background monitoring service to prevent runtime errors

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 15, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

PR #374 fixes three service-level reliability issues in SystemManager: WQL injection vulnerability in DiskHealthService, lock contention overhead in OperationLockService, and resource disposal race condition in PingMonitorService. Changes are documented in CHANGELOG.md version 0.48.12.

Changes

Service Reliability Fixes

Layer / File(s) Summary
DiskHealthService WQL Injection Prevention
SysManager/SysManager/Services/DiskHealthService.cs
EnrichWithReliability extends WQL objectId escaping to include single quotes alongside existing backslash and double-quote escaping.
OperationLockService Atomic Concurrency Model
SysManager/SysManager/Services/OperationLockService.cs
TryAcquire and Release are rewritten to use ConcurrentDictionary.TryAdd and TryRemove instead of explicit _lock object, eliminating lock statements while preserving ActiveOperations property-change notifications.
PingMonitorService CTS Disposal Timing
SysManager/SysManager/Services/PingMonitorService.cs
Stop() now defers _cts disposal until the background pump task completes (_loop.IsCompleted), preventing ObjectDisposedException during cancellation.
Release Notes Documentation
CHANGELOG.md
Version 0.48.12 Unreleased entry documents all three fixes: WQL escaping, lock removal with atomic operations, and CTS disposal timing.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • laurentiu021/SystemManager#357: Modifies PingMonitorService.Stop() shutdown behavior and exception handling in the same method updated by this PR.
  • laurentiu021/SystemManager#368: Updates OperationLockServiceEdgeCaseTests to validate property-change notifications that are directly affected by this PR's OperationLockService refactoring.

Poem

🐰 Three fixes hop into the night,
Escaping quotes and locks so tight,
A task that waits its turn to go,
Release the chains, let safety flow! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically summarizes the three main changes: WQL escaping, atomic lock operations, and safe CTS disposal. It directly corresponds to the primary fixes in the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/medium-cq-batch-2

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 83.33333% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...sManager/SysManager/Services/PingMonitorService.cs 0.00% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@SysManager/SysManager/Services/PingMonitorService.cs`:
- Around line 59-64: The current Stop logic disposes and nulls _cts prematurely
when _loop is still running, leaking the CTS on timeout; instead attach a
continuation to the background task (_loop) that disposes and nulls _cts only
after the task completes. Modify the Stop/cleanup code around symbols _loop and
_cts so that if Wait(1500) times out you do NOT drop _cts to null immediately
but call _loop?.ContinueWith(...) (or await/async completion) to perform
_cts?.Dispose() and set _cts = null once the task finishes, ensuring disposal
runs exactly when the background task has completed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 00f15256-bdce-43dd-b47c-b37a7a1706d0

📥 Commits

Reviewing files that changed from the base of the PR and between 742326d and 80f1612.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • SysManager/SysManager/Services/DiskHealthService.cs
  • SysManager/SysManager/Services/OperationLockService.cs
  • SysManager/SysManager/Services/PingMonitorService.cs
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Analyze (csharp)
  • GitHub Check: Build & unit tests
🔇 Additional comments (4)
CHANGELOG.md (1)

9-19: LGTM!

SysManager/SysManager/Services/DiskHealthService.cs (1)

72-72: LGTM!

SysManager/SysManager/Services/OperationLockService.cs (2)

49-55: LGTM!


82-84: LGTM!

Comment on lines +59 to 64
// Only dispose CTS if the loop actually completed; otherwise the
// background task still holds a reference to the token and would
// throw ObjectDisposedException on next cancellation check.
if (_loop is { IsCompleted: true })
_cts?.Dispose();
_cts = null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify Stop() has no deferred CTS disposal path in the current branch.
sed -n '51,90p' SysManager/SysManager/Services/PingMonitorService.cs
rg -n --type=cs -C2 'ContinueWith|_cts\?\.Dispose\(' SysManager/SysManager/Services/PingMonitorService.cs

Repository: laurentiu021/SystemManager

Length of output: 1913


Defer CTS disposal until the background task actually completes.

The conditional disposal at line 62 only executes when _loop is already completed. However, if Wait(1500) times out, _loop is still running and the CTS is not disposed—the reference is then lost to null at line 64. This creates a resource leak on repeated Start/Stop cycles.

The background task still holds a reference to the cancellation token, so immediate disposal would cause an ObjectDisposedException on its next cancellation check. Instead, chain the disposal to execute after the loop truly completes:

Proposed fix
-            if (_loop is { IsCompleted: true })
-                _cts?.Dispose();
+            if (_loop is { IsCompleted: true })
+            {
+                _cts?.Dispose();
+            }
+            else if (_loop != null && _cts != null)
+            {
+                var ctsToDispose = _cts;
+                _ = _loop.ContinueWith(
+                    _ => ctsToDispose.Dispose(),
+                    CancellationToken.None,
+                    TaskContinuationOptions.ExecuteSynchronously,
+                    TaskScheduler.Default);
+            }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Only dispose CTS if the loop actually completed; otherwise the
// background task still holds a reference to the token and would
// throw ObjectDisposedException on next cancellation check.
if (_loop is { IsCompleted: true })
_cts?.Dispose();
_cts = null;
// Only dispose CTS if the loop actually completed; otherwise the
// background task still holds a reference to the token and would
// throw ObjectDisposedException on next cancellation check.
if (_loop is { IsCompleted: true })
{
_cts?.Dispose();
}
else if (_loop != null && _cts != null)
{
var ctsToDispose = _cts;
_ = _loop.ContinueWith(
_ => ctsToDispose.Dispose(),
CancellationToken.None,
TaskContinuationOptions.ExecuteSynchronously,
TaskScheduler.Default);
}
_cts = null;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@SysManager/SysManager/Services/PingMonitorService.cs` around lines 59 - 64,
The current Stop logic disposes and nulls _cts prematurely when _loop is still
running, leaking the CTS on timeout; instead attach a continuation to the
background task (_loop) that disposes and nulls _cts only after the task
completes. Modify the Stop/cleanup code around symbols _loop and _cts so that if
Wait(1500) times out you do NOT drop _cts to null immediately but call
_loop?.ContinueWith(...) (or await/async completion) to perform _cts?.Dispose()
and set _cts = null once the task finishes, ensuring disposal runs exactly when
the background task has completed.

@laurentiu021
laurentiu021 merged commit 451e20b into main May 15, 2026
5 checks passed
@laurentiu021
laurentiu021 deleted the fix/medium-cq-batch-2 branch May 15, 2026 07:19
laurentiu021 added a commit that referenced this pull request May 22, 2026
… CQ-008, CQ-015) (#374)

Co-authored-by: laurentiu021 <laurentiu021@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants