]> git.karo-electronics.de Git - karo-tx-linux.git/commit
idr: fix unexpected ID-removal when idr_remove(unallocated_id)
authorLai Jiangshan <laijs@cn.fujitsu.com>
Thu, 22 May 2014 00:44:08 +0000 (10:44 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Thu, 22 May 2014 00:44:08 +0000 (10:44 +1000)
commita0f9d0cee7e3ca3319f62b3a3cde88601199f3c4
treef82fbc089decb3c9c2a0a1195d1b489d40b53a60
parent431345bfd2cb5941105e9f9cb21e91b2ad6cb703
idr: fix unexpected ID-removal when idr_remove(unallocated_id)

If unallocated_id = (ANY * idr_max(idp->layers) + existing_id) is passed
to idr_remove().  The existing_id will be removed unexpectedly.

The following test shows this unexpected id-removal:

static void test4(void)
{
int id;
DEFINE_IDR(test_idr);

printk(KERN_INFO "Start test4\n");
id = idr_alloc(&test_idr, (void *)1, 42, 43, GFP_KERNEL);
BUG_ON(id != 42);
idr_remove(&test_idr, 42 + IDR_SIZE);
TEST_BUG_ON(idr_find(&test_idr, 42) != (void *)1);
idr_destroy(&test_idr);
printk(KERN_INFO "End of test4\n");
}

ida_remove() shares the similar problem.

It happens only when the caller tries to free an unallocated ID which is
the caller's fault.  It is not a bug.  But it is better to add the proper
check and complain rather than removing an existing_id silently.

Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Acked-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
lib/idr.c