Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:Update
qemu-linux-user
0392-memory-Revert-memory-accept-mismatc.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0392-memory-Revert-memory-accept-mismatc.patch of Package qemu-linux-user
From: Jose R Ziviani <jose.ziviani@suse.com> Date: Mon, 10 May 2021 08:07:49 -0600 Subject: memory: Revert "memory: accept mismatching sizes in memory_region_access_valid" Git-commit: 5d971f9e672507210e77d020d89e0e89165c8fc9 References: bsc#1172382 CVE-2020-13754 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@nongnu.org Reviewed-by: Richard Henderson <rth@twiddle.net> 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@redhat.com> Message-Id: <20200610134731.1514409-1-mst@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Jose R. Ziviani <jose.ziviani@suse.com> --- memory.c | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/memory.c b/memory.c index 2108c691fd3481e6999cb187433e..2bbd1ae0b340ea7f9fede9140c3e 100644 --- a/memory.c +++ b/memory.c @@ -1148,35 +1148,24 @@ bool memory_region_access_valid(MemoryRegion *mr, unsigned size, bool is_write) { - 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)) { 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)) { - return false; - } + if (size > mr->ops->valid.max_access_size + || size < mr->ops->valid.min_access_size) { + return false; } - return true; }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor