The branch main has been updated by dougm:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=5b9b55fbc43261fc1467caaf7f2b70b8f752e479

commit 5b9b55fbc43261fc1467caaf7f2b70b8f752e479
Author:     Doug Moore <do...@freebsd.org>
AuthorDate: 2022-12-22 20:31:57 +0000
Commit:     Doug Moore <do...@freebsd.org>
CommitDate: 2022-12-22 20:31:57 +0000

    iommu_gas: avoid overflow in bounds check
    
    Change the range test in iommu_gas_match_one from '< ubound' to '<=
    ubound', and pass a smaller-by-one ubound parameter to it, to avoid
    overflow in ubound calculation.
    
    Reported by:    andrew
    Reviewed by:    andrew (previous version)
    MFC after:      3 days
    Differential Revision:  https://reviews.freebsd.org/D37764
---
 sys/dev/iommu/iommu_gas.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/sys/dev/iommu/iommu_gas.c b/sys/dev/iommu/iommu_gas.c
index 5654bc7ed8de..86fc3bfa093c 100644
--- a/sys/dev/iommu/iommu_gas.c
+++ b/sys/dev/iommu/iommu_gas.c
@@ -309,7 +309,7 @@ struct iommu_gas_match_args {
 
 /*
  * The interval [beg, end) is a free interval between two iommu_map_entries.
- * Addresses can be allocated only in the range [lbound, ubound). Try to
+ * Addresses can be allocated only in the range [lbound, ubound]. Try to
  * allocate space in the free interval, subject to the conditions expressed by
  * a, and return 'true' if and only if the allocation attempt succeeds.
  */
@@ -332,10 +332,10 @@ iommu_gas_match_one(struct iommu_gas_match_args *a, 
iommu_gaddr_t beg,
        start = roundup2(beg, a->common->alignment);
        if (start < beg)
                return (false);
-       end = MIN(end - IOMMU_PAGE_SIZE, ubound);
+       end = MIN(end - IOMMU_PAGE_SIZE - 1, ubound);
        offset = a->offset;
        size = a->size;
-       if (start + offset + size > end)
+       if (start + offset + size - 1 > end)
                return (false);
 
        /* Check for and try to skip past boundary crossing. */
@@ -349,7 +349,7 @@ iommu_gas_match_one(struct iommu_gas_match_args *a, 
iommu_gaddr_t beg,
                beg = roundup2(start + offset + 1, a->common->boundary);
                start = roundup2(beg, a->common->alignment);
 
-               if (start + offset + size > end ||
+               if (start + offset + size - 1 > end ||
                    !vm_addr_bound_ok(start + offset, size,
                    a->common->boundary)) {
                        /*
@@ -453,7 +453,7 @@ iommu_gas_find_space(struct iommu_domain *domain,
         * Walk the big-enough ranges tree until one satisfies alignment
         * requirements, or violates lowaddr address requirement.
         */
-       addr = a->common->lowaddr + 1;
+       addr = a->common->lowaddr;
        for (curr = first; curr != NULL;
            curr = iommu_gas_next(curr, min_free)) {
                if ((first = RB_LEFT(curr, rb_entry)) != NULL &&
@@ -464,7 +464,7 @@ iommu_gas_find_space(struct iommu_domain *domain,
                        return (0);
                }
                if (curr->end >= addr) {
-                       /* All remaining ranges >= addr */
+                       /* All remaining ranges > addr */
                        break;
                }
                if ((first = RB_RIGHT(curr, rb_entry)) != NULL &&
@@ -502,14 +502,14 @@ iommu_gas_find_space(struct iommu_domain *domain,
            curr = iommu_gas_next(curr, min_free)) {
                if ((first = RB_LEFT(curr, rb_entry)) != NULL &&
                    iommu_gas_match_one(a, first->last, curr->start,
-                   addr + 1, domain->end)) {
+                   addr + 1, domain->end - 1)) {
                        RB_INSERT_PREV(iommu_gas_entries_tree,
                            &domain->rb_root, curr, a->entry);
                        return (0);
                }
                if ((first = RB_RIGHT(curr, rb_entry)) != NULL &&
                    iommu_gas_match_one(a, curr->end, first->first,
-                   addr + 1, domain->end)) {
+                   addr + 1, domain->end - 1)) {
                        RB_INSERT_NEXT(iommu_gas_entries_tree,
                            &domain->rb_root, curr, a->entry);
                        return (0);

Reply via email to