mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 10:41:38 -04:00
idr: Fix handling of IDs above INT_MAX
Khalid reported that the kernel selftests are currently failing:
selftests: test_bpf.sh
========================================
test_bpf: [FAIL]
not ok 1..8 selftests: test_bpf.sh [FAIL]
He bisected it to 6ce711f275 ("idr: Make
1-based IDRs more efficient").
The root cause is doing a signed comparison in idr_alloc_u32() instead
of an unsigned comparison. I went looking for any similar problems and
found a couple (which would each result in the failure to warn in two
situations that aren't supposed to happen).
I knocked up a few test-cases to prove that I was right and added them
to the test-suite.
Reported-by: Khalid Aziz <[email protected]>
Tested-by: Khalid Aziz <[email protected]>
Signed-off-by: Matthew Wilcox <[email protected]>
This commit is contained in:
parent
3d4d5d6186
commit
4b0ad07653
2 changed files with 59 additions and 6 deletions
|
|
@ -178,6 +178,55 @@ void idr_get_next_test(int base)
|
|||
idr_destroy(&idr);
|
||||
}
|
||||
|
||||
int idr_u32_cb(int id, void *ptr, void *data)
|
||||
{
|
||||
BUG_ON(id < 0);
|
||||
BUG_ON(ptr != DUMMY_PTR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void idr_u32_test1(struct idr *idr, u32 handle)
|
||||
{
|
||||
static bool warned = false;
|
||||
u32 id = handle;
|
||||
int sid = 0;
|
||||
void *ptr;
|
||||
|
||||
BUG_ON(idr_alloc_u32(idr, DUMMY_PTR, &id, id, GFP_KERNEL));
|
||||
BUG_ON(id != handle);
|
||||
BUG_ON(idr_alloc_u32(idr, DUMMY_PTR, &id, id, GFP_KERNEL) != -ENOSPC);
|
||||
BUG_ON(id != handle);
|
||||
if (!warned && id > INT_MAX)
|
||||
printk("vvv Ignore these warnings\n");
|
||||
ptr = idr_get_next(idr, &sid);
|
||||
if (id > INT_MAX) {
|
||||
BUG_ON(ptr != NULL);
|
||||
BUG_ON(sid != 0);
|
||||
} else {
|
||||
BUG_ON(ptr != DUMMY_PTR);
|
||||
BUG_ON(sid != id);
|
||||
}
|
||||
idr_for_each(idr, idr_u32_cb, NULL);
|
||||
if (!warned && id > INT_MAX) {
|
||||
printk("^^^ Warnings over\n");
|
||||
warned = true;
|
||||
}
|
||||
BUG_ON(idr_remove(idr, id) != DUMMY_PTR);
|
||||
BUG_ON(!idr_is_empty(idr));
|
||||
}
|
||||
|
||||
void idr_u32_test(int base)
|
||||
{
|
||||
DEFINE_IDR(idr);
|
||||
idr_init_base(&idr, base);
|
||||
idr_u32_test1(&idr, 10);
|
||||
idr_u32_test1(&idr, 0x7fffffff);
|
||||
idr_u32_test1(&idr, 0x80000000);
|
||||
idr_u32_test1(&idr, 0x80000001);
|
||||
idr_u32_test1(&idr, 0xffe00000);
|
||||
idr_u32_test1(&idr, 0xffffffff);
|
||||
}
|
||||
|
||||
void idr_checks(void)
|
||||
{
|
||||
unsigned long i;
|
||||
|
|
@ -248,6 +297,9 @@ void idr_checks(void)
|
|||
idr_get_next_test(0);
|
||||
idr_get_next_test(1);
|
||||
idr_get_next_test(4);
|
||||
idr_u32_test(4);
|
||||
idr_u32_test(1);
|
||||
idr_u32_test(0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in a new issue