Commit aa8e4fc68d8024cd3132035d13c3cefa7baeac8f

Authored by Linus Torvalds
1 parent 9ead64974b

bitmap: fix end condition in bitmap_find_free_region

Guennadi Liakhovetski noticed that the end condition for the loop in
bitmap_find_free_region() is wrong, and the "return if error" was also
using the wrong conditional that would only trigger if the bitmap was an
exact multiple of the allocation size, which is not necessarily the case
with dma_alloc_from_coherent().

Such a failure would end up in bitmap_find_free_region() accessing
beyond the end of the bitmap.

Reported-by: Guennadi Liakhovetski <lg@denx.de>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 1 changed file with 8 additions and 8 deletions Side-by-side Diff

... ... @@ -948,15 +948,15 @@
948 948 */
949 949 int bitmap_find_free_region(unsigned long *bitmap, int bits, int order)
950 950 {
951   - int pos; /* scans bitmap by regions of size order */
  951 + int pos, end; /* scans bitmap by regions of size order */
952 952  
953   - for (pos = 0; pos < bits; pos += (1 << order))
954   - if (__reg_op(bitmap, pos, order, REG_OP_ISFREE))
955   - break;
956   - if (pos == bits)
957   - return -ENOMEM;
958   - __reg_op(bitmap, pos, order, REG_OP_ALLOC);
959   - return pos;
  953 + for (pos = 0 ; (end = pos + (1 << order)) <= bits; pos = end) {
  954 + if (!__reg_op(bitmap, pos, order, REG_OP_ISFREE))
  955 + continue;
  956 + __reg_op(bitmap, pos, order, REG_OP_ALLOC);
  957 + return pos;
  958 + }
  959 + return -ENOMEM;
960 960 }
961 961 EXPORT_SYMBOL(bitmap_find_free_region);
962 962