Signed integer overflow in idr_grow() growth loop causes kernel hang or panic-sized kmalloc
Summary
idr_grow() doubles nf with nf=2*nf+1 in signed int until nf>want. For want>=2^29 loop exits with nf=2^30-1 or 2^31-1 driving kmalloc to request 16-32GiB panicking/hanging under M_WAITOK. For want==INT_MAX predicate INT_MAX<=INT_MAX true so loop runs once more 2*INT_MAX+1 is signed overflow wraps to -1 and -1<=want keeps loop spinning forever holding lwkt token. Starting from 255=2^8-1 after k iterations nf=2^(8+k)-1. At k=23 nf=2^31-1=INT_MAX. want flows from caller-supplied start/sid: idr_alloc passes start directly idr_get_new_above stores idr_maxwant=max(maxwant sid) before returning -EAGAIN retry pattern calls idr_pre_get which grows to idr_maxwant. No upper-bound check on want sid or nf anywhere in file. In-tree DRM callers currently bounded (drm_gem.c start=1 amdgpu PASID 16-bit) but API provides no guardrail. Impact: system-wide DoS livelock on token or kernel panic. Any caller of idr KPI reachable once DRM device open. Latent DoS primitive fires moment any caller forwards user-influenced integer into start/sid.
No comments yet.