[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[qemu-xen stable-4.14] memory: Revert "memory: accept mismatching sizes in memory_region_access_valid"



commit b14cd263ad87a4c3a83308f093841d247eb711f1
Author:     Michael S. Tsirkin <mst@xxxxxxxxxx>
AuthorDate: Wed Jun 10 09:47:49 2020 -0400
Commit:     Michael Roth <mdroth@xxxxxxxxxxxxxxxxxx>
CommitDate: Thu Aug 27 00:03:16 2020 -0500

    memory: Revert "memory: accept mismatching sizes in 
memory_region_access_valid"
    
    Memory API documentation documents valid .min_access_size and 
.max_access_size
    fields and explains that any access outside these boundaries is blocked.
    
    This is what devices seem to assume.
    
    However this is not what the implementation does: it simply
    ignores the boundaries unless there's an "accepts" callback.
    
    Naturally, this breaks a bunch of devices.
    
    Revert to the documented behaviour.
    
    Devices that want to allow any access can just drop the valid field,
    or add the impl field to have accesses converted to appropriate
    length.
    
    Cc: qemu-stable@xxxxxxxxxx
    Reviewed-by: Richard Henderson <rth@xxxxxxxxxxx>
    Fixes: CVE-2020-13754
    Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1842363
    Fixes: a014ed07bd5a ("memory: accept mismatching sizes in 
memory_region_access_valid")
    Signed-off-by: Michael S. Tsirkin <mst@xxxxxxxxxx>
    Message-Id: <20200610134731.1514409-1-mst@xxxxxxxxxx>
    Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
    (cherry picked from commit 5d971f9e672507210e77d020d89e0e89165c8fc9)
    Signed-off-by: Michael Roth <mdroth@xxxxxxxxxxxxxxxxxx>
---
 memory.c | 29 +++++++++--------------------
 1 file changed, 9 insertions(+), 20 deletions(-)

diff --git a/memory.c b/memory.c
index 601b749906..e31aed6446 100644
--- a/memory.c
+++ b/memory.c
@@ -1352,35 +1352,24 @@ bool memory_region_access_valid(MemoryRegion *mr,
                                 bool is_write,
                                 MemTxAttrs attrs)
 {
-    int access_size_min, access_size_max;
-    int access_size, i;
-
-    if (!mr->ops->valid.unaligned && (addr & (size - 1))) {
+    if (mr->ops->valid.accepts
+        && !mr->ops->valid.accepts(mr->opaque, addr, size, is_write, attrs)) {
         return false;
     }
 
-    if (!mr->ops->valid.accepts) {
-        return true;
-    }
-
-    access_size_min = mr->ops->valid.min_access_size;
-    if (!mr->ops->valid.min_access_size) {
-        access_size_min = 1;
+    if (!mr->ops->valid.unaligned && (addr & (size - 1))) {
+        return false;
     }
 
-    access_size_max = mr->ops->valid.max_access_size;
+    /* Treat zero as compatibility all valid */
     if (!mr->ops->valid.max_access_size) {
-        access_size_max = 4;
+        return true;
     }
 
-    access_size = MAX(MIN(size, access_size_max), access_size_min);
-    for (i = 0; i < size; i += access_size) {
-        if (!mr->ops->valid.accepts(mr->opaque, addr + i, access_size,
-                                    is_write, attrs)) {
-            return false;
-        }
+    if (size > mr->ops->valid.max_access_size
+        || size < mr->ops->valid.min_access_size) {
+        return false;
     }
-
     return true;
 }
 
--
generated by git-patchbot for /home/xen/git/qemu-xen.git#stable-4.14



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.