xen/arm: domain_build: Check if the address fits the range of physical address

handle_pci_range() and map_range_to_domain() take addr and len as uint64_t
parameters. Then frame numbers are obtained from addr and len by right shifting
with PAGE_SHIFT. The frame numbers are expressed using unsigned long.

Now if 64-bit >> PAGE_SHIFT, the result will have 52-bits as valid. On a 32-bit
system, 'unsigned long' is 32-bits. Thus, there is a potential loss of value
when the result is stored as 'unsigned long'.

To mitigate this issue, we check if the starting and end address can be
contained within the range of physical address supported on the system. If not,
then an appropriate error is returned.

Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
Reviewed-by: Julien Grall <jgrall@amazon.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
This commit is contained in:
Ayan Kumar Halder authored and Julien Grall committed 2023-05-26 13:13:19 +01:00
1 parent adbcc656ff
commit 133f6df947
1 file changed
+14
+14
View File
@@ -1643,6 +1643,13 @@ static int __init handle_pci_range(const struct dt_device_node *dev,
paddr_t start, end; paddr_t start, end;
int res; int res;
if ( (addr != (paddr_t)addr) || (((paddr_t)~0 - addr) < len) )
{
printk(XENLOG_ERR "%s: [0x%"PRIx64", 0x%"PRIx64"] exceeds the maximum allowed PA width (%u bits)",
dt_node_full_name(dev), addr, (addr + len), PADDR_BITS);
return -ERANGE;
}
start = addr & PAGE_MASK; start = addr & PAGE_MASK;
end = PAGE_ALIGN(addr + len); end = PAGE_ALIGN(addr + len);
res = rangeset_remove_range(mem_holes, PFN_DOWN(start), PFN_DOWN(end - 1)); res = rangeset_remove_range(mem_holes, PFN_DOWN(start), PFN_DOWN(end - 1));
@@ -2333,6 +2340,13 @@ int __init map_range_to_domain(const struct dt_device_node *dev,
struct domain *d = mr_data->d; struct domain *d = mr_data->d;
int res; int res;
if ( (addr != (paddr_t)addr) || (((paddr_t)~0 - addr) < len) )
{
printk(XENLOG_ERR "%s: [0x%"PRIx64", 0x%"PRIx64"] exceeds the maximum allowed PA width (%u bits)",
dt_node_full_name(dev), addr, (addr + len), PADDR_BITS);
return -ERANGE;
}
/* /*
* reserved-memory regions are RAM carved out for a special purpose. * reserved-memory regions are RAM carved out for a special purpose.
* They are not MMIO and therefore a domain should not be able to * They are not MMIO and therefore a domain should not be able to
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.