idr: Warn if old iterators see large IDs
authorMatthew Wilcox <mawilcox@microsoft.com>
Tue, 28 Nov 2017 20:50:12 +0000 (15:50 -0500)
committerMatthew Wilcox <mawilcox@microsoft.com>
Tue, 6 Feb 2018 21:41:28 +0000 (16:41 -0500)
Now that the IDR can be used to store large IDs, it is possible somebody
might only partially convert their old code and use the iterators which
can only handle IDs up to INT_MAX.  It's probably unwise to show them a
truncated ID, so settle for spewing warnings to dmesg, and terminating
the iteration.

Signed-off-by: Matthew Wilcox <mawilcox@microsoft.com>
lib/idr.c

index 3df44d528b68759eeef3351e3ca7f5f23488aae5..b47055efceb0a88e3d44d1490ab1b6c94a370365 100644 (file)
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -159,7 +159,11 @@ int idr_for_each(const struct idr *idr,
        void __rcu **slot;
 
        radix_tree_for_each_slot(slot, &idr->idr_rt, &iter, 0) {
-               int ret = fn(iter.index, rcu_dereference_raw(*slot), data);
+               int ret;
+
+               if (WARN_ON_ONCE(iter.index > INT_MAX))
+                       break;
+               ret = fn(iter.index, rcu_dereference_raw(*slot), data);
                if (ret)
                        return ret;
        }
@@ -187,6 +191,9 @@ void *idr_get_next(struct idr *idr, int *nextid)
        if (!slot)
                return NULL;
 
+       if (WARN_ON_ONCE(iter.index > INT_MAX))
+               return NULL;
+
        *nextid = iter.index;
        return rcu_dereference_raw(*slot);
 }