mirror of
https://github.com/X11Libre/xserver.git
synced 2026-11-15 05:23:40 +00:00
dri2: fix off-by-one heap overflow in do_get_buffers() buffer array
The buffers array was sized min(count, DRI2BufferHiz) + 1, but count is already capped at DRI2BufferHiz + 1 by the check above. The min() only changes anything at that exact boundary (count == DRI2BufferHiz + 1), where it throws away the array's '+1 slack' right when the main loop can legitimately fill all 'count' slots itself, leaving no room for a synthesized real/fake front buffer the client didn't explicitly request. Trigger: a DRI2-capable client sends DRI2GetBuffers/DRI2GetBuffersWithFormat with 11 attachment entries (the maximum allowed), none of them DRI2BufferFrontLeft but at least one DRI2BufferBackLeft (so need_real_front ends up set) -- the post-loop synthesis writes buffers[11], one past the 11-element allocation. Deterministic, no OOM required. Fix: allocate count + 1 slots unconditionally; count is already bounded, so this is never a meaningfully larger allocation. Found via a fleet-directed alloc-fail/UAF sweep of Xext/, not from a live crash report. Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
This commit is contained in:
parent
4016148b81
commit
c03bc789ae
1 changed files with 10 additions and 2 deletions
|
|
@ -540,9 +540,17 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
|
|||
&& (pDraw->height == pPriv->height);
|
||||
|
||||
/* Since we deduplicate attachments in the buffers array, there cannot be
|
||||
* more entries than there are attachments.
|
||||
* more entries than there are attachments, plus one slot for a
|
||||
* synthesized real/fake front buffer the client didn't explicitly
|
||||
* request. 'count' is already capped at DRI2BufferHiz + 1 by the check
|
||||
* above, so this is never a large allocation; clamping it again via
|
||||
* min(count, DRI2BufferHiz) is wrong at that exact boundary (count ==
|
||||
* DRI2BufferHiz + 1) -- it throws away the "+1" slack right when the
|
||||
* loop below can legitimately use every one of the 'count' slots itself,
|
||||
* leaving no room for the synthesized buffer and writing one past the
|
||||
* end of this array.
|
||||
*/
|
||||
DRI2BufferPtr *buffers = calloc((min(count, DRI2BufferHiz) + 1), sizeof(buffers[0]));
|
||||
DRI2BufferPtr *buffers = calloc(count + 1, sizeof(buffers[0]));
|
||||
if (!buffers)
|
||||
goto err_out;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue