Skip to content

Automated fix for refs/heads/shopify-fixes - #52

Open
github-actions[bot] wants to merge 4 commits into
shopify-fixesfrom
create-pull-request/patch-9531953
Open

Automated fix for refs/heads/shopify-fixes#52
github-actions[bot] wants to merge 4 commits into
shopify-fixesfrom
create-pull-request/patch-9531953

Conversation

@github-actions

@github-actions github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown

PanCakes to the rescue!

We noticed that our 'sanity' test was going to fail, but we think we can fix that automatically, so we put together this PR to do just that!

If you'd like to opt-out of these PR's, add yourself to NO_AUTOFIX_USERS in .github/workflows/pr-auto-fix.yaml

rwstauner and others added 4 commits September 3, 2026 12:50
Epoll1Poller::Work() collected pending Epoll1EventHandle* pointers under
the poller mutex, then released the mutex before draining them via
ExecutePendingActions(). Handles are poller-owned memory, recycled via
free_epoll1_handles_list_ and only freed in Close() (called from
~Epoll1Poller), so the unlocked drain was safe when it was introduced
(grpc#30828, 2022): nothing could free a handle mid-drain.

EventEngine fork support (grpc#38441, grpc#38980, grpc#39739, 2025) broke that
invariant. During fork a c-ares DNS socket handle can be orphaned
(~GrpcPolledFdPosix -> OrphanHandle) and the poller torn down
concurrently with a Work() iteration that is still draining
pending_events. The handle is freed by Close() and its slot reused, so
ExecutePendingActions() dereferences recycled memory as a closure pointer.

Fix: hold the poller mutex across the whole collect-and-drain sequence so
a handle in pending_events cannot be freed while it is being
dereferenced. This is deadlock-free: Work() never takes the handle mutex,
and schedule_poll_again() only flips a bool or enqueues a thread-pool
task. The poll-based poller is unaffected because it uses ref-counted
handles.

Adds a regression test (epoll1_poller_handle_lifetime_test) that
interleaves a Work() drain with an OrphanHandle + Close(); without the fix
it fails under ASan with a stack matching the production crash.
…af-fork-pending-events' into fixes

* ares-resolver-fork-crash:
  Drain c-ares callbacks during resolver destruction
  Fix SIGABRT in AresResolver destructor during fork

* ares-channel-null:
  [event_engine] c-ares: Return early if channel is null rather than asserting

* uaf-fork-pending-events:
  [posix_engine] Exit Epoll1Poller::Work if poller is closed once lock is acquired
  [posix_engine] Fix use-after-free draining epoll1 events during fork
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