Thanks to visit codestin.com
Credit goes to github.com

Skip to content

virtio-devices: copy VSock header from guest - #7530

Merged
rbradford merged 1 commit into
cloud-hypervisor:mainfrom
p4zuu:vsock_toctou
Jan 27, 2026
Merged

rbradford merged 1 commit into
cloud-hypervisor:mainfrom
p4zuu:vsock_toctou

Conversation

@p4zuu

@p4zuu p4zuu commented Dec 1, 2025

Copy link
Copy Markdown
Contributor

This issue has been reported privately to @rbradford.

VsockPacket::hdr holds a raw pointer to the address of the VSock packet header, which is in guest memory. It opens the door to double-fetch (or TOCTOU) race conditions. Therefore, VSockPacket::hdr content can't be trusted since it can be arbitrarily changed by the guest, at any time.

To mitigate this, we can copy the header content to an array in VMM's memory that the guest can't modify.

I managed to trigger this race condition by changing the len field header just before this line. This triggers a slice out-of-bounds and makes the VMM process panic. Since the packet header is allocated by the guest kernel, the PoC needs a guest kernel module to scan kernel memory and change the len field. I can provide the source files for the PoC.

It seems that some (maybe most) of the VSock code comes from firecracker, which had the same issue but fixed it. This PR takes some pieces of code from the firecracker codebase.

Also, I'm not a VSock expert so a more experienced reviewer would be appreciated.

@p4zuu
p4zuu requested a review from a team as a code owner December 1, 2025 18:51
@rbradford

Copy link
Copy Markdown
Member

@alyssais Is this something you could take a look at? I think you might be the most experienced in this code.

@alyssais

alyssais commented Dec 2, 2025

Copy link
Copy Markdown
Member

Can do, but probably not this week.

@rbradford

Copy link
Copy Markdown
Member

Can do, but probably not this week.

@alyssais Happy New Year - any chance to you can take a look at this?

@alyssais alyssais left a comment

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.

Looks fine. I think it would be nicer to use GuestMemory but this fix shouldn't be blocked on that since it has a security impact.

Comment thread virtio-devices/src/vsock/packet.rs Outdated
hdr: *mut u8,
// We still hold the header address in guest memory. We need to write back the modified
// header in RX buffers.
guest_hdr_ptr: *mut u8,

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.

Would be nice to use a GuestAddress here to be more robust against similar issues in future. Might also simplify from_tx_virtq_head and from_rx_virtq_head.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

guest_hdr_ptr is now guest_hdr_addr and it's a GuestAddr

@p4zuu

p4zuu commented Jan 23, 2026

Copy link
Copy Markdown
Contributor Author

Looks fine. I think it would be nicer to use GuestMemory but this fix shouldn't be blocked on that since it has a security impact.

Thanks for the review! I'll have the time this weekend to update with GuestMemory use

@p4zuu

p4zuu commented Jan 27, 2026

Copy link
Copy Markdown
Contributor Author

@alyssais PR updated using GuestAddress to keep track of packet header guest address, and GuestMemory trait to write back to guest memory

Comment thread virtio-devices/src/vsock/packet.rs Outdated

let hdr_ptr =
get_host_address_range(desc_chain.memory(), guest_hdr_addr, VSOCK_PKT_HDR_SIZE)
.ok_or(VsockError::GuestMemory)?;

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.

How about dest_chain.memory().get_slice(guest_hdr_addr, VSOCK_PKT_HDR_SIZE), and then we avoid the unsafe?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Much cleaner indeed. Updated

Comment thread virtio-devices/src/vsock/packet.rs Outdated
// we need to copy the content of the header in the VMM's memory.
// After the copy, the hdr content can be trusted since the guest can't change its
// content anymore.

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.

nit: Maybe we could maybe we could condense some of the whitespace in this block. Do we need quite so many empty lines?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

do you mean something like:

// To avoid TOCTOU issues when reading/writing the VSock packet header in guest memory,
// we need to copy the content of the header in the VMM's memory. After the copy, the
// hdr content can be trusted since the guest can't change its content anymore.
let mut hdr = [0u8; VSOCK_PKT_HDR_SIZE];

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 was referring to the whitespace on lines 143, 145, 246, 248. I like vertical whitespace when it helps group logical bits together e.g. grouping where the data is created, size calculated and then copied would make a good grouping. If you use too much whitespace it can be hard to see the logical groups (since then you can't see where another logical group of functionality is)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Makes sense. I just remove those whitespaces

VsockPacket::hdr holds a raw pointer to the address of the VSock packet
header, which is in guest memory. It opens the door to double-fetch
(or TOCTOU) race conditions. Therefore, VSockPacket::hdr content can't
be trusted since it can be arbitrarily changed by the guest, at any
time.

To mitigate this, we can copy the header content to an array in VMM's
memory that the guest can't modify.

Signed-off-by: Thomas Leroy <[email protected]>
@rbradford
rbradford enabled auto-merge January 27, 2026 18:46
@rbradford

Copy link
Copy Markdown
Member

@p4zuu Thank you for your PR. It's now 🚀

@rbradford
rbradford added this pull request to the merge queue Jan 27, 2026
Merged via the queue into cloud-hypervisor:main with commit 929df76 Jan 27, 2026
43 checks passed
@likebreath likebreath added the bug-fix Bug fix to include in release notes label Feb 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug-fix Bug fix to include in release notes

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

5 participants