(Imported from
b53f8c187de8)
Author: Rusty Russell <rusty@rustorp.com.au>
Date: Thu Jun 10 13:27:51 2010 -0700
Since idtree assigns sequentially, it rarely reaches high numbers.
But such numbers can be forced with idr_get_new_above(), and that
reveals two bugs:
1) Crash in sub_remove() caused by pa array being too short.
2) Shift by more than 32 in _idr_find(), which is undefined, causing
the "outside the current tree" optimization to misfire and return NULL.
static int sub_remove(struct idtree *idp, int shift, int id)
{
struct idtree_layer *p = idp->top;
- struct idtree_layer **pa[MAX_LEVEL];
+ struct idtree_layer **pa[1+MAX_LEVEL];
struct idtree_layer ***paa = &pa[0];
int n;
* This tests to see if bits outside the current tree are
* present. If so, tain't one of ours!
*/
- if ((id & ~(~0 << MAX_ID_SHIFT)) >> (n + IDTREE_BITS))
+ if (n + IDTREE_BITS < 31 &&
+ (id & ~(~0 << MAX_ID_SHIFT)) >> (n + IDTREE_BITS))
return NULL;
/* Mask off upper bits we don't use for the search. */