|
|
6e7d01 |
From 13f4ebe4708f4f4dc20d710e475a42d520459860 Mon Sep 17 00:00:00 2001
|
|
|
6e7d01 |
From: Jon Maloy <jmaloy@redhat.com>
|
|
|
6e7d01 |
Date: Wed, 21 Apr 2021 22:30:03 -0400
|
|
|
6e7d01 |
Subject: [PATCH 4/7] memory: Revert "memory: accept mismatching sizes in
|
|
|
6e7d01 |
memory_region_access_valid"
|
|
|
6e7d01 |
MIME-Version: 1.0
|
|
|
6e7d01 |
Content-Type: text/plain; charset=UTF-8
|
|
|
6e7d01 |
Content-Transfer-Encoding: 8bit
|
|
|
6e7d01 |
|
|
|
6e7d01 |
RH-Author: Jon Maloy <jmaloy@redhat.com>
|
|
|
6e7d01 |
Message-id: <20210421223006.19650-4-jmaloy@redhat.com>
|
|
|
6e7d01 |
Patchwork-id: 101480
|
|
|
6e7d01 |
O-Subject: [RHEL-8.5.0 qemu-kvm PATCH v2 3/6] memory: Revert "memory: accept mismatching sizes in memory_region_access_valid"
|
|
|
6e7d01 |
Bugzilla: 1842478
|
|
|
6e7d01 |
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
|
|
|
6e7d01 |
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
|
|
6e7d01 |
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
|
|
6e7d01 |
|
|
|
6e7d01 |
From: "Michael S. Tsirkin" <mst@redhat.com>
|
|
|
6e7d01 |
|
|
|
6e7d01 |
Memory API documentation documents valid .min_access_size and .max_access_size
|
|
|
6e7d01 |
fields and explains that any access outside these boundaries is blocked.
|
|
|
6e7d01 |
|
|
|
6e7d01 |
This is what devices seem to assume.
|
|
|
6e7d01 |
|
|
|
6e7d01 |
However this is not what the implementation does: it simply
|
|
|
6e7d01 |
ignores the boundaries unless there's an "accepts" callback.
|
|
|
6e7d01 |
|
|
|
6e7d01 |
Naturally, this breaks a bunch of devices.
|
|
|
6e7d01 |
|
|
|
6e7d01 |
Revert to the documented behaviour.
|
|
|
6e7d01 |
|
|
|
6e7d01 |
Devices that want to allow any access can just drop the valid field,
|
|
|
6e7d01 |
or add the impl field to have accesses converted to appropriate
|
|
|
6e7d01 |
length.
|
|
|
6e7d01 |
|
|
|
6e7d01 |
Cc: qemu-stable@nongnu.org
|
|
|
6e7d01 |
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
|
|
6e7d01 |
Fixes: CVE-2020-13754
|
|
|
6e7d01 |
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1842363
|
|
|
6e7d01 |
Fixes: a014ed07bd5a ("memory: accept mismatching sizes in memory_region_access_valid")
|
|
|
6e7d01 |
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
|
|
6e7d01 |
Message-Id: <20200610134731.1514409-1-mst@redhat.com>
|
|
|
6e7d01 |
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
6e7d01 |
|
|
|
6e7d01 |
(cherry picked from commit 5d971f9e672507210e77d020d89e0e89165c8fc9)
|
|
|
6e7d01 |
Signed-off-by: Jon Maloy <jmaloy@redhat.com>
|
|
|
6e7d01 |
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
|
|
6e7d01 |
---
|
|
|
6e7d01 |
memory.c | 29 +++++++++--------------------
|
|
|
6e7d01 |
1 file changed, 9 insertions(+), 20 deletions(-)
|
|
|
6e7d01 |
|
|
|
6e7d01 |
diff --git a/memory.c b/memory.c
|
|
|
6e7d01 |
index 5a4a80842d..0cfcb72a5a 100644
|
|
|
6e7d01 |
--- a/memory.c
|
|
|
6e7d01 |
+++ b/memory.c
|
|
|
6e7d01 |
@@ -1351,35 +1351,24 @@ bool memory_region_access_valid(MemoryRegion *mr,
|
|
|
6e7d01 |
bool is_write,
|
|
|
6e7d01 |
MemTxAttrs attrs)
|
|
|
6e7d01 |
{
|
|
|
6e7d01 |
- int access_size_min, access_size_max;
|
|
|
6e7d01 |
- int access_size, i;
|
|
|
6e7d01 |
-
|
|
|
6e7d01 |
- if (!mr->ops->valid.unaligned && (addr & (size - 1))) {
|
|
|
6e7d01 |
+ if (mr->ops->valid.accepts
|
|
|
6e7d01 |
+ && !mr->ops->valid.accepts(mr->opaque, addr, size, is_write, attrs)) {
|
|
|
6e7d01 |
return false;
|
|
|
6e7d01 |
}
|
|
|
6e7d01 |
|
|
|
6e7d01 |
- if (!mr->ops->valid.accepts) {
|
|
|
6e7d01 |
- return true;
|
|
|
6e7d01 |
- }
|
|
|
6e7d01 |
-
|
|
|
6e7d01 |
- access_size_min = mr->ops->valid.min_access_size;
|
|
|
6e7d01 |
- if (!mr->ops->valid.min_access_size) {
|
|
|
6e7d01 |
- access_size_min = 1;
|
|
|
6e7d01 |
+ if (!mr->ops->valid.unaligned && (addr & (size - 1))) {
|
|
|
6e7d01 |
+ return false;
|
|
|
6e7d01 |
}
|
|
|
6e7d01 |
|
|
|
6e7d01 |
- access_size_max = mr->ops->valid.max_access_size;
|
|
|
6e7d01 |
+ /* Treat zero as compatibility all valid */
|
|
|
6e7d01 |
if (!mr->ops->valid.max_access_size) {
|
|
|
6e7d01 |
- access_size_max = 4;
|
|
|
6e7d01 |
+ return true;
|
|
|
6e7d01 |
}
|
|
|
6e7d01 |
|
|
|
6e7d01 |
- access_size = MAX(MIN(size, access_size_max), access_size_min);
|
|
|
6e7d01 |
- for (i = 0; i < size; i += access_size) {
|
|
|
6e7d01 |
- if (!mr->ops->valid.accepts(mr->opaque, addr + i, access_size,
|
|
|
6e7d01 |
- is_write, attrs)) {
|
|
|
6e7d01 |
- return false;
|
|
|
6e7d01 |
- }
|
|
|
6e7d01 |
+ if (size > mr->ops->valid.max_access_size
|
|
|
6e7d01 |
+ || size < mr->ops->valid.min_access_size) {
|
|
|
6e7d01 |
+ return false;
|
|
|
6e7d01 |
}
|
|
|
6e7d01 |
-
|
|
|
6e7d01 |
return true;
|
|
|
6e7d01 |
}
|
|
|
6e7d01 |
|
|
|
6e7d01 |
--
|
|
|
6e7d01 |
2.27.0
|
|
|
6e7d01 |
|