Skip to content

Bounds-check EventHandlerBase::is_ready() to fix out-of-bounds read (#2376)#3170

Open
PavelGuzenfeld wants to merge 1 commit into
ros2:rollingfrom
PavelGuzenfeld:fix/issue-2376-event-handler-is-ready-bounds
Open

Bounds-check EventHandlerBase::is_ready() to fix out-of-bounds read (#2376)#3170
PavelGuzenfeld wants to merge 1 commit into
ros2:rollingfrom
PavelGuzenfeld:fix/issue-2376-event-handler-is-ready-bounds

Conversation

@PavelGuzenfeld
Copy link
Copy Markdown

EventHandlerBase::is_ready() indexes wait_set.events[wait_set_event_index_], but that index is only assigned once the handler is added to the wait set via add_to_wait_set(). If is_ready() runs first — e.g. a publisher/subscription event thread racing node setup — the index is not valid for this wait set and the access reads out of bounds, which can segfault (observed with ASan during a lifecycle configure).

This initializes wait_set_event_index_ to an always-out-of-range sentinel and makes is_ready() return false when the index is not within the wait set's events, instead of dereferencing it.

Adds a regression test that calls is_ready() on a handler that was never added to a wait set.

Builds on @aosmw's work in #2376; per @clalancette's review there, initializing the index alone is not sufficient (it could still point at another slot), so the bounds check in is_ready() is the actual guard.


Some of this change was produced with Claude Opus 4.8 (Anthropic).

…2376)

is_ready() indexed wait_set.events with wait_set_event_index_, which is only
assigned once the handler is added to that wait set via add_to_wait_set(). If
is_ready() runs first (e.g. a publisher/subscription event thread racing node
setup), the index is uninitialized or refers to a different wait set, so the
access reads out of bounds and can segfault (observed with ASan during lifecycle
configure).

Initialize wait_set_event_index_ and make is_ready() return false when the index
is not within the wait set's events instead of dereferencing it. Initializing
alone is not sufficient (index 0 may still not be this handler's slot), so the
bounds check is the actual guard.

Adds a regression test that calls is_ready() on a handler that was never added to
a wait set.

Refs ros2#2376

Co-authored-by: Mike Wake <michael.wake@aosgrp.com.au>
Generated-by: Claude Opus 4.8 (Anthropic)
Signed-off-by: Pavel Guzenfeld <pavelguzenfeld@gmail.com>
Signed-off-by: Mike Wake <michael.wake@aosgrp.com.au>
@PavelGuzenfeld PavelGuzenfeld force-pushed the fix/issue-2376-event-handler-is-ready-bounds branch from 7aa7462 to 048bc4d Compare June 6, 2026 22:24
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.

1 participant