Skip to content

bdev/nvme: prevent UAF by unregistering connect poller and null-guarding qpair#68

Merged
derekbit merged 1 commit into
longhorn:longhorn-v25.09from
c3y1huang:11698-fix-spdk_tgt_sigsegv
Dec 1, 2025
Merged

bdev/nvme: prevent UAF by unregistering connect poller and null-guarding qpair#68
derekbit merged 1 commit into
longhorn:longhorn-v25.09from
c3y1huang:11698-fix-spdk_tgt_sigsegv

Conversation

@c3y1huang

Copy link
Copy Markdown

Which issue(s) this PR fixes:

Issue longhorn/longhorn#11698

What this PR does / why we need it:

longhorn/longhorn#11698 (comment)

Special notes for your reviewer:

Additional documentation or context

Copilot AI 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.

Pull request overview

This PR addresses a Use-After-Free (UAF) vulnerability in the NVMe bdev module that can occur during connect/disconnect/reset sequences. The fix adds defensive guards in the connect poller callback to detect when resources have been freed, and ensures the poller is unregistered during channel destruction before clearing the qpair pointer.

Key changes:

  • Added NULL checks in bdev_nvme_reset_check_qpair_connected to prevent accessing freed nvme_qpair or controller resources
  • Ensured connect_poller is unregistered in bdev_nvme_destroy_ctrlr_channel_cb before clearing pointers to prevent callbacks from accessing freed memory
  • Added bidirectional NULL-ing of qpair references (both ctrlr_ch->qpair and nvme_qpair->ctrlr_ch) to prevent dangling pointers

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.

Comment thread module/bdev/nvme/bdev_nvme.c Outdated
…ing qpair

longhorn/longhorn-11698

Signed-off-by: Chin-Ya Huang <chin-ya.huang@suse.com>
@c3y1huang
c3y1huang force-pushed the 11698-fix-spdk_tgt_sigsegv branch from 647965a to fcef5df Compare November 27, 2025 07:14
@c3y1huang
c3y1huang marked this pull request as ready for review November 28, 2025 04:02
"Unregistering connect_poller %p during channel destroy "
"(ctrlr_ch=%p, nvme_qpair=%p).\n",
ctrlr_ch->connect_poller, ctrlr_ch, nvme_qpair);
spdk_poller_unregister(&ctrlr_ch->connect_poller);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I haven't checked the codes for registering and unregistering connect poller. Some questions

  • When will the connect register be registered?
  • It seems the UAF doesn't always happen. Do you know why?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

When will the connect register be registered?

It's registered during reset/failover: https://github.com/longhorn/spdk/blob/longhorn-v25.05/module/bdev/nvme/bdev_nvme.c#L2460. A detach during this window can trigger a race.

It seems the UAF doesn't always happen. Do you know why?

It’s a race between three async pieces that can arrive in different orders:

  1. Channel destroy callback (bdev_nvme_destroy_ctrlr_channel_cb)
  2. Disconnect callback (bdev_nvme_disconnected_qpair_cb)
  3. The connect poller firing (bdev_nvme_reset_check_qpair_connected)

Ref: longhorn/longhorn#11698 (comment)

@derekbit
derekbit merged commit e1d5238 into longhorn:longhorn-v25.09 Dec 1, 2025
2 checks passed
@c3y1huang
c3y1huang deleted the 11698-fix-spdk_tgt_sigsegv branch December 1, 2025 05:14
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.

3 participants