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 sizes. 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 properly. This is an alternative fix for the one attempted in commit617f591fc4
. Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com> (cherry picked from commit966f567432
)
This commit is contained in:
parent
d1ca47e124
commit
b33f487a7c
|
@ -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)
|
|||
randr_crtc->gammaBlue,
|
||||
randr_crtc->gammaSize);
|
||||
} 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]));
|
||||
}
|
||||
|
||||
xf86RandR12CrtcReloadGamma(crtc);
|
||||
|
|
Loading…
Reference in New Issue