diff options
author | Chirantan Ekbote <chirantan@chromium.org> | 2019-10-29 12:09:11 +0900 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-10-29 23:37:22 +0000 |
commit | 232ada718754c8f97f1e2035062102821afc4099 (patch) | |
tree | c0975c963e3cf99e2cb22433529638103a587838 /devices/src | |
parent | ec5916daa056b2ad68a5dc2a7c604299aa3e2c8f (diff) | |
download | crosvm-232ada718754c8f97f1e2035062102821afc4099.tar crosvm-232ada718754c8f97f1e2035062102821afc4099.tar.gz crosvm-232ada718754c8f97f1e2035062102821afc4099.tar.bz2 crosvm-232ada718754c8f97f1e2035062102821afc4099.tar.lz crosvm-232ada718754c8f97f1e2035062102821afc4099.tar.xz crosvm-232ada718754c8f97f1e2035062102821afc4099.tar.zst crosvm-232ada718754c8f97f1e2035062102821afc4099.zip |
virtio: Convert ring index to u64 earlier in Queue::pop
The `next_avail` field is a Wrapping<u16> but we pull out the underlying u16 when calculating the descriptor index address offset in Queue::pop and only convert the result to a u64 after applying all the operations. This can cause a u16 overflow if the queue size is the max allowed (2^15). Instead, convert to a u64 immediately after calculating the index so that the rest of the operations are carried out as u64s and will not overflow. BUG=chromium:1018319 TEST=`cros_fuzz reproduce` and unit tests Change-Id: I49743e239e2a407498d862c5137930f3f0cdf72a Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1884404 Reviewed-by: Dylan Reid <dgreid@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Daniel Verkamp <dverkamp@chromium.org> Auto-Submit: Chirantan Ekbote <chirantan@chromium.org>
Diffstat (limited to 'devices/src')
-rw-r--r-- | devices/src/virtio/queue.rs | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/devices/src/virtio/queue.rs b/devices/src/virtio/queue.rs index 2b2ce3d..02f48e5 100644 --- a/devices/src/virtio/queue.rs +++ b/devices/src/virtio/queue.rs @@ -310,7 +310,7 @@ impl Queue { return None; } - let desc_idx_addr_offset = (4 + (self.next_avail.0 % queue_size) * 2) as u64; + let desc_idx_addr_offset = 4 + (u64::from(self.next_avail.0 % queue_size) * 2); let desc_idx_addr = mem.checked_offset(self.avail_ring, desc_idx_addr_offset)?; // This index is checked below in checked_new. |