virtio-queue: enforce VirtIO queue data structure alignment constraints
The VirtIO Spec 1.0, sec 2.4 defines the alignment constraints for
VirtIO queue's descriptor table, available ring and used ring.
So enforce the alignment constraints in Queue::is_valid().
@@ -306,6 +306,15 @@ impl Queue {
used_ring_size
);
false
+ } else if desc_table.offset() & 0xf != 0 {
+ error!("virtio queue descriptor table breaks alignment contraints");
+ false
+ } else if avail_ring.offset() & 0x1 != 0 {
+ error!("virtio queue available ring breaks alignment contraints");
+ false
+ } else if used_ring.offset() & 0x3 != 0 {
+ error!("virtio queue used ring breaks alignment contraints");
+ false
} else {
true
}
@@ -712,14 +721,20 @@ pub(crate) mod tests {
q.desc_table = GuestAddress(0xffffffff);
assert!(!q.is_valid(m));
+ q.desc_table = GuestAddress(0x1001);
+ assert!(!q.is_valid(m));
q.desc_table = vq.dtable_start();
q.avail_ring = GuestAddress(0xffffffff);
assert!(!q.is_valid(m));
+ q.avail_ring = GuestAddress(0x1001);
+ assert!(!q.is_valid(m));
q.avail_ring = vq.avail_start();
q.used_ring = GuestAddress(0xffffffff);
assert!(!q.is_valid(m));
+ q.used_ring = GuestAddress(0x1001);
+ assert!(!q.is_valid(m));
q.used_ring = vq.used_start();
{
