Skip to content

Prevent LibGpiodV2 native abort on null edge event - #2601

Open
krwq with Copilot wants to merge 3 commits into
mainfrom
copilot/fix-unchecked-null-abort-process
Open

Prevent LibGpiodV2 native abort on null edge event#2601
krwq with Copilot wants to merge 3 commits into
mainfrom
copilot/fix-unchecked-null-abort-process

Conversation

Copilot AI commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Fixed #2600

A service watching an input pin via LibGpiodV2Driver could be killed by an uncatchable native abort() (gpiod_edge_event_copy: Assertion 'event' failed) — even with no real edge activity. EdgeEventBuffer.GetEvent forwarded the pointer from gpiod_edge_event_buffer_get_event straight into gpiod_edge_event_copy; that function returns NULL for an unpopulated index and the copy call starts with assert(event), so the whole process aborts with no managed exception to catch.

Changes

  • EdgeEventBuffer.GetEvent — null-check the handle before copying; throw a handleable GpiodException instead of passing null into the native call.
  • LibGpiodV2EventObserver — bound the observer loop by min(ReadEdgeEvents(...), GetNumEvents()) so unpopulated buffer slots are never read. gpiod_line_request_read_edge_events can report a count larger than what's actually retrievable from the buffer; this avoids hitting the null path during normal operation.
using EdgeEventNotFreeable edgeEventHandle = LibgpiodV2.gpiod_edge_event_buffer_get_event(Handle, index);
if (edgeEventHandle.IsInvalid)
{
    throw new GpiodException($"Edge event at index {index} is not populated in the buffer.");
}

Together these turn a process-killing abort into, at worst, a recoverable managed error, while the loop bound prevents the error path from being reached in the common case.

Notes

  • Full build/test could not be validated in this environment (Azure DevOps feeds for Microsoft.DotNet.Arcade.Sdk are unreachable). The affected proxies are internal native-interop wrappers exercised only by hardware integration tests, so no isolated unit test was added.

Co-authored-by: krwq <660048+krwq@users.noreply.github.com>
@dotnet-policy-service dotnet-policy-service Bot added the area-System.Device.Gpio Contains types for using general-purpose I/O (GPIO) pins label Aug 20, 2026
Co-authored-by: krwq <660048+krwq@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix unchecked null issue causing abort in libgpiod Prevent LibGpiodV2 native abort on null edge event Aug 20, 2026
Copilot AI requested a review from krwq August 20, 2026 16:11
@raffaeler
raffaeler marked this pull request as ready for review August 20, 2026 18:07
Copilot AI lite review requested due to automatic review settings August 20, 2026 18:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses a reliability issue in the System.Device.Gpio libgpiod v2 interop path where a NULL edge event pointer could be forwarded into gpiod_edge_event_copy, triggering an uncatchable native abort() and terminating the host process.

Changes:

  • Add a null/invalid-handle guard in EdgeEventBuffer.GetEvent to throw a managed GpiodException instead of passing a null pointer into native code.
  • Bound the edge-event handling loop in LibGpiodV2EventObserver to the number of events actually stored in the buffer (min(ReadEdgeEvents, GetNumEvents)), avoiding reads of unpopulated buffer slots.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/System.Device.Gpio/System/Device/Gpio/Drivers/LibGpiodV2EventObserver.cs Bounds event processing by buffered event count to avoid unpopulated reads.
src/System.Device.Gpio/Interop/Unix/libgpiod/V2/Proxies/EdgeEventBuffer.cs Adds invalid-handle check before copying an edge event to prevent native abort.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines 229 to 230
EdgeEvent edgeEvent = edgeEventBuffer.GetEvent((ulong)i);
HandleEdgeEvent(edgeEvent);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-System.Device.Gpio Contains types for using general-purpose I/O (GPIO) pins

Projects

None yet

Development

Successfully merging this pull request may close these issues.

LibGpiodV2: unchecked null from gpiod_edge_event_buffer_get_event aborts the process (gpiod_edge_event_copy: Assertion 'event' failed)

4 participants