Commit 966f5674 authored by Mario Kleiner's avatar Mario Kleiner Committed by Povilas Kanapickas
Browse files

xfree86: Avoid crash in xf86RandR12CrtcSetGamma() memcpy path.

If randrp->palette_size is zero, the memcpy() path can read past the
end of the randr_crtc's gammaRed/Green/Blue tables if the hw crtc's
gamma_size is greater than the randr_crtc's gammaSize.

Avoid this by clamping the to-be-copied size to the smaller of both

Note that during regular server startup, the memcpy() path is only
taken initially twice, but then a suitable palette is created for
use during a session. Therefore during an actual running X-Session,
the xf86RandR12CrtcComputeGamma() will be used, which makes sure that
data is properly up- or down-sampled for mismatching source and
target crtc gamma sizes.

This should avoid reading past randr_crtc gamma memory for gpu's
with big crtc->gamma_size, e.g., AMD/MALI/KOMEDA 4096 slots, or
Intel Icelake and later with 262145 slots.

Tested against modesetting-ddx and amdgpu-ddx under screen color
depth 24 (8 bpc) and 30 (10 bpc) to make sure that clamping happens

This is an alternative fix for the one attempted in commit


Signed-off-by: Mario Kleiner's avatarMario Kleiner <>
parent 6c1e6429
......@@ -1358,6 +1358,7 @@ xf86RandR12CrtcSetGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
xf86CrtcPtr crtc = randr_crtc->devPrivate;
int max_size = crtc->gamma_size;
if (crtc->funcs->gamma_set == NULL)
return FALSE;
......@@ -1372,12 +1373,15 @@ xf86RandR12CrtcSetGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
} else {
if (max_size > randr_crtc->gammaSize)
max_size = randr_crtc->gammaSize;
memcpy(crtc->gamma_red, randr_crtc->gammaRed,
crtc->gamma_size * sizeof(crtc->gamma_red[0]));
max_size * sizeof(crtc->gamma_red[0]));
memcpy(crtc->gamma_green, randr_crtc->gammaGreen,
crtc->gamma_size * sizeof(crtc->gamma_green[0]));
max_size * sizeof(crtc->gamma_green[0]));
memcpy(crtc->gamma_blue, randr_crtc->gammaBlue,
crtc->gamma_size * sizeof(crtc->gamma_blue[0]));
max_size * sizeof(crtc->gamma_blue[0]));
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment