Skip to content

Commit

Permalink
ida: Free allocated bitmap in error path
Browse files Browse the repository at this point in the history
If a bitmap needs to be allocated, and then by the time the thread
is scheduled to be run again all the indices which would satisfy the
allocation have been allocated then we would leak the allocation.  Almost
impossible to hit in practice, but a trivial fix.  Found by Coverity.

Fixes: f32f004 ("ida: Convert to XArray")
Reported-by: coverity-bot <[email protected]>
Reviewed-by: Kees Cook <[email protected]>
Signed-off-by: Matthew Wilcox (Oracle) <[email protected]>
  • Loading branch information
Matthew Wilcox (Oracle) committed Oct 7, 2020
1 parent dd841a7 commit a219b85
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/idr.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,7 @@ int ida_alloc_range(struct ida *ida, unsigned int min, unsigned int max,
goto retry;
nospc:
xas_unlock_irqrestore(&xas, flags);
kfree(alloc);
return -ENOSPC;
}
EXPORT_SYMBOL(ida_alloc_range);
Expand Down
29 changes: 29 additions & 0 deletions tools/testing/radix-tree/idr-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -523,8 +523,27 @@ static void *ida_random_fn(void *arg)
return NULL;
}

static void *ida_leak_fn(void *arg)
{
struct ida *ida = arg;
time_t s = time(NULL);
int i, ret;

rcu_register_thread();

do for (i = 0; i < 1000; i++) {
ret = ida_alloc_range(ida, 128, 128, GFP_KERNEL);
if (ret >= 0)
ida_free(ida, 128);
} while (time(NULL) < s + 2);

rcu_unregister_thread();
return NULL;
}

void ida_thread_tests(void)
{
DEFINE_IDA(ida);
pthread_t threads[20];
int i;

Expand All @@ -536,6 +555,16 @@ void ida_thread_tests(void)

while (i--)
pthread_join(threads[i], NULL);

for (i = 0; i < ARRAY_SIZE(threads); i++)
if (pthread_create(&threads[i], NULL, ida_leak_fn, &ida)) {
perror("creating ida thread");
exit(1);
}

while (i--)
pthread_join(threads[i], NULL);
assert(ida_is_empty(&ida));
}

void ida_tests(void)
Expand Down

0 comments on commit a219b85

Please sign in to comment.