Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ida: Free allocated bitmap in error path

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: f32f004cddf8 ("ida: Convert to XArray")
Reported-by: coverity-bot <keescook+coverity-bot@chromium.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>

+30
+1
lib/idr.c
··· 470 470 goto retry; 471 471 nospc: 472 472 xas_unlock_irqrestore(&xas, flags); 473 + kfree(alloc); 473 474 return -ENOSPC; 474 475 } 475 476 EXPORT_SYMBOL(ida_alloc_range);
+29
tools/testing/radix-tree/idr-test.c
··· 523 523 return NULL; 524 524 } 525 525 526 + static void *ida_leak_fn(void *arg) 527 + { 528 + struct ida *ida = arg; 529 + time_t s = time(NULL); 530 + int i, ret; 531 + 532 + rcu_register_thread(); 533 + 534 + do for (i = 0; i < 1000; i++) { 535 + ret = ida_alloc_range(ida, 128, 128, GFP_KERNEL); 536 + if (ret >= 0) 537 + ida_free(ida, 128); 538 + } while (time(NULL) < s + 2); 539 + 540 + rcu_unregister_thread(); 541 + return NULL; 542 + } 543 + 526 544 void ida_thread_tests(void) 527 545 { 546 + DEFINE_IDA(ida); 528 547 pthread_t threads[20]; 529 548 int i; 530 549 ··· 555 536 556 537 while (i--) 557 538 pthread_join(threads[i], NULL); 539 + 540 + for (i = 0; i < ARRAY_SIZE(threads); i++) 541 + if (pthread_create(&threads[i], NULL, ida_leak_fn, &ida)) { 542 + perror("creating ida thread"); 543 + exit(1); 544 + } 545 + 546 + while (i--) 547 + pthread_join(threads[i], NULL); 548 + assert(ida_is_empty(&ida)); 558 549 } 559 550 560 551 void ida_tests(void)