Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DoS issue when using virtio with rust-vmm/vm-memory #98

Merged
merged 2 commits into from
Jun 10, 2020

Conversation

andreeaflorescu
Copy link
Member

We have identified an issue in the rust-vmm vm-memory crate that leads to a denial-of-service (DoS) issue if the crate is used in a VMM in conjunction with virtio. The issue affects both vm-memory releases (v0.1.0 and v0.2.0). In our environment, we reproduced this with musl builds on x86_64, and with all aarch64 builds. This PR fixes the issue. The fix will also be applied to the aforementioned releases. All consumers should switch to vm-memory v0.1.1 or v0.2.1.

Issue Description

In rust-vmm/vm-memory, the functions read_obj and write_obj are not doing atomic accesses for all combinations of platform and libc implementations. These reads and writes translate to memcpy, which may be performing byte-by-byte copies. Using vm-memory in the virtio implementation can cause undefined behavior, as descriptor indexes require 2-byte atomic accesses.

Impact

The issue can affect any virtio/emulated device which expects atomic writes for base types longer than 1 byte.

Observed impact: When the network stack is under load, the driver will try to clear a used descriptor before the index of the descriptor is fully written by the device. When this issue is triggered, the virtio-net device will be unable to transmit packets. This leads to VMs using rust-vmm/vm-memory having their network effectively disconnected by outside network traffic, resulting in both a DoS vector and an availability issue under normal at-load operations.

Affected Systems

For a VMM to be affected, it must run on aarch64 (built with either musl or glibc), or on x86_64 with a musl build. All VMMs using rust-vmm/vm-memory (any release) in a production scenario, and that take arbitrary traffic over the virtio-net device, are confirmed to be at risk of a DOS. All VMMs using rust-vmm/vm-memory (any release) in a production scenario with a virtio-net deice are under availability risk. All VMMs using rust-vmm/vm-memory (any release) in a production scenario using other devices that expect atomic reads for more than 1-byte values may also be affected, but we are unaware of any risk for other devices (beyond the guest freezing its own virtio stack).

Mitigation

This PR fixes the issue. The fix will also be applied to the aforementioned releases. All consumers should switch to vm-memory v0.1.1 or v0.2.1. On x86_64 glibc builds the fix may lead to a 5% network throughput degradation.

Some memcpy implementations are copying bytes one at a time, which
is slow and also breaks the virtio specification by splitting writes
to the fields of the virtio descriptor. So, reimplement memcpy in Rust
and copy in larger pieces, according to the largest possible alignment
allowed by the pointer values.

Signed-off-by: Serban Iorga <seriorga@amazon.com>
Signed-off-by: Andreea Florescu <fandree@amazon.com>
Signed-off-by: Alexandru Agache <aagch@amazon.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
@andreeaflorescu
Copy link
Member Author

Related to: #93

This crate was using a pretty old version of Rust (1.35.0) which
didn't have the required features.

Signed-off-by: Andreea Florescu <fandree@amazon.com>
@sameo
Copy link

sameo commented May 28, 2020

I suspect this has an impact on the x86_64+glibc target where memcpy is surely ISA optimized.
I'm fine with pushing that PR through, but if you're ok with that I'll open an issue to track the potential performance regressions.

@andreeaflorescu
Copy link
Member Author

regressions

Yap, we should do that.

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.

None yet

5 participants