diff options
author | Daniel Verkamp <dverkamp@chromium.org> | 2019-12-06 10:17:45 +1100 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-12-10 02:24:14 +0000 |
commit | f21572c7187c8beb9c6bfea6446351ae93200d01 (patch) | |
tree | 019623d7ddec73324d741a3b902591c08d77e8fe | |
parent | aa77ea40454c460a7189860f1ea146c45e444dad (diff) | |
download | crosvm-f21572c7187c8beb9c6bfea6446351ae93200d01.tar crosvm-f21572c7187c8beb9c6bfea6446351ae93200d01.tar.gz crosvm-f21572c7187c8beb9c6bfea6446351ae93200d01.tar.bz2 crosvm-f21572c7187c8beb9c6bfea6446351ae93200d01.tar.lz crosvm-f21572c7187c8beb9c6bfea6446351ae93200d01.tar.xz crosvm-f21572c7187c8beb9c6bfea6446351ae93200d01.tar.zst crosvm-f21572c7187c8beb9c6bfea6446351ae93200d01.zip |
qcow: avoid out-of-bounds access in alloc_refblocks
When all refblocks are consumed, the loop looking for the first free cluster would access the element at refcounts[refcounts.len()], which is out of bounds. Modify the free cluster search loop to check that the index is in bounds before accessing it. BUG=chromium:1030751 TEST=qcow_fuzzer Change-Id: Ib2384b9cf1edeaadb99be5fc67c27a55c03fc6e9 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1953766 Tested-by: Daniel Verkamp <dverkamp@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Dylan Reid <dgreid@chromium.org> Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
-rw-r--r-- | qcow/src/qcow.rs | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/qcow/src/qcow.rs b/qcow/src/qcow.rs index dd8c1a2..10998f5 100644 --- a/qcow/src/qcow.rs +++ b/qcow/src/qcow.rs @@ -742,11 +742,14 @@ impl QcowFile { let mut ref_table = vec![0; refcount_table_entries as usize]; let mut first_free_cluster: u64 = 0; for refblock_addr in &mut ref_table { - while refcounts[first_free_cluster as usize] != 0 { - first_free_cluster += 1; + loop { if first_free_cluster >= refcounts.len() as u64 { return Err(Error::NotEnoughSpaceForRefcounts); } + if refcounts[first_free_cluster as usize] == 0 { + break; + } + first_free_cluster += 1; } *refblock_addr = first_free_cluster * cluster_size; |