modesetting: Fix ms_covering_crtc() segfault with non-modesetting slave primary
ms_covering_crtc() uses RRFirstOutput() to determine a primary output to fall back to if a drawable is overlapping a slave output. If the primary output is a slave output, RRFirstOutput() will return a slave output even if passed a master ScreenPtr. ms_covering_crtc() dereferences the output's devPrivate, which is invalid for non-modesetting outputs, and can crash. Changing RRFirstOutput() could have unintended side effects for other callers, so this change replaces the call to RRFirstOutput() with ms_first_output(). ms_first_output() ignores the primary output if it doesn't match the given ScreenPtr, choosing the first connected output instead. Signed-off-by: Alex Goins <agoins@nvidia.com>
This commit is contained in:
parent
c82f814313
commit
3ef9029ace
|
@ -90,6 +90,39 @@ ms_crtc_on(xf86CrtcPtr crtc)
|
|||
return crtc->enabled && drmmode_crtc->dpms_mode == DPMSModeOn;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the first output which is connected to an active CRTC on this screen.
|
||||
*
|
||||
* RRFirstOutput() will return an output from a slave screen if it is primary,
|
||||
* which is not the behavior that ms_covering_crtc() wants.
|
||||
*/
|
||||
|
||||
static RROutputPtr ms_first_output(ScreenPtr pScreen)
|
||||
{
|
||||
rrScrPriv(pScreen);
|
||||
RROutputPtr output;
|
||||
int i, j;
|
||||
|
||||
if (!pScrPriv)
|
||||
return NULL;
|
||||
|
||||
if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc &&
|
||||
(pScrPriv->primaryOutput->pScreen == pScreen)) {
|
||||
return pScrPriv->primaryOutput;
|
||||
}
|
||||
|
||||
for (i = 0; i < pScrPriv->numCrtcs; i++) {
|
||||
RRCrtcPtr crtc = pScrPriv->crtcs[i];
|
||||
|
||||
for (j = 0; j < pScrPriv->numOutputs; j++) {
|
||||
output = pScrPriv->outputs[j];
|
||||
if (output->crtc == crtc)
|
||||
return output;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the crtc covering 'box'. If two crtcs cover a portion of
|
||||
* 'box', then prefer the crtc with greater coverage.
|
||||
|
@ -135,7 +168,7 @@ ms_covering_crtc(ScreenPtr pScreen, BoxPtr box, Bool screen_is_ms)
|
|||
ScreenPtr slave;
|
||||
|
||||
if (dixPrivateKeyRegistered(rrPrivKey))
|
||||
primary_output = RRFirstOutput(scrn->pScreen);
|
||||
primary_output = ms_first_output(scrn->pScreen);
|
||||
if (!primary_output || !primary_output->crtc)
|
||||
return NULL;
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user