drmmode: Use a copy of the converted mode on resize
Avoid a potential use-after-free of the copied mode string by reusing the converted kernel mode on resize. ==19897== Invalid read of size 8 ==19897== at 0x661C330: ??? (strcpy.S:1308) ==19897== by 0x8618AE7: drmmode_set_mode_major (drmmode_display.c:293) ==19897== by 0x8618E6F: drmmode_xf86crtc_resize (drmmode_display.c:1299) ==19897== by 0x529A77: xf86RandR12ScreenSetSize (xf86RandR12.c:708) ==19897== by 0x4BD528: ProcRRSetScreenSize (rrscreen.c:301) ==19897== by 0x42B820: Dispatch (dispatch.c:432) ==19897== by 0x4254C9: main (main.c:289) ==19897== Address 0x72e91e0 is 0 bytes inside a block of size 9 free'd ==19897== at 0x4C23DBC: free (vg_replace_malloc.c:325) ==19897== by 0x48424F: xf86DeleteMode (xf86Mode.c:1921) ==19897== by 0x4942B7: xf86ProbeOutputModes (xf86Crtc.c:1572) ==19897== by 0x5290BB: xf86RandR12GetInfo12 (xf86RandR12.c:1551) ==19897== by 0x5313AE: RRGetInfo (rrinfo.c:202) ==19897== by 0x4BCCAA: rrGetScreenResources (rrscreen.c:337) ==19897== by 0x42B820: Dispatch (dispatch.c:432) ==19897== by 0x4254C9: main (main.c:289) Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
772f8236d5
commit
690fbd1a64
|
|
@ -57,6 +57,7 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
drmmode_ptr drmmode;
|
||||
drmModeModeInfo kmode;
|
||||
drmModeCrtcPtr mode_crtc;
|
||||
dri_bo *cursor;
|
||||
dri_bo *rotate_bo;
|
||||
|
|
@ -302,52 +303,20 @@ drmmode_crtc_dpms(xf86CrtcPtr drmmode_crtc, int mode)
|
|||
}
|
||||
|
||||
static Bool
|
||||
drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
|
||||
Rotation rotation, int x, int y)
|
||||
drmmode_apply(xf86CrtcPtr crtc)
|
||||
{
|
||||
ScrnInfoPtr scrn = crtc->scrn;
|
||||
intel_screen_private *intel = intel_get_screen_private(scrn);
|
||||
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
|
||||
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||
drmmode_ptr drmmode = drmmode_crtc->drmmode;
|
||||
int saved_x, saved_y;
|
||||
Rotation saved_rotation;
|
||||
DisplayModeRec saved_mode;
|
||||
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
|
||||
uint32_t *output_ids;
|
||||
int output_count = 0;
|
||||
int ret = TRUE;
|
||||
int i;
|
||||
int fb_id;
|
||||
drmModeModeInfo kmode;
|
||||
unsigned int pitch = scrn->displayWidth * intel->cpp;
|
||||
|
||||
if (drmmode->fb_id == 0) {
|
||||
ret = drmModeAddFB(drmmode->fd,
|
||||
scrn->virtualX, scrn->virtualY,
|
||||
scrn->depth, scrn->bitsPerPixel,
|
||||
pitch, intel->front_buffer->handle,
|
||||
&drmmode->fb_id);
|
||||
if (ret < 0) {
|
||||
ErrorF("failed to add fb\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
saved_mode = crtc->mode;
|
||||
saved_x = crtc->x;
|
||||
saved_y = crtc->y;
|
||||
saved_rotation = crtc->rotation;
|
||||
|
||||
crtc->mode = *mode;
|
||||
crtc->x = x;
|
||||
crtc->y = y;
|
||||
crtc->rotation = rotation;
|
||||
int fb_id, x, y;
|
||||
int i, ret;
|
||||
|
||||
output_ids = calloc(sizeof(uint32_t), xf86_config->num_output);
|
||||
if (!output_ids) {
|
||||
ret = FALSE;
|
||||
goto done;
|
||||
}
|
||||
if (!output_ids)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < xf86_config->num_output; i++) {
|
||||
xf86OutputPtr output = xf86_config->output[i];
|
||||
|
|
@ -375,9 +344,9 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
|
|||
crtc->gamma_blue, crtc->gamma_size);
|
||||
#endif
|
||||
|
||||
drmmode_ConvertToKMode(crtc->scrn, &kmode, mode);
|
||||
|
||||
|
||||
x = crtc->x;
|
||||
y = crtc->y;
|
||||
fb_id = drmmode->fb_id;
|
||||
if (drmmode_crtc->rotate_fb_id) {
|
||||
fb_id = drmmode_crtc->rotate_fb_id;
|
||||
|
|
@ -385,11 +354,13 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
|
|||
y = 0;
|
||||
}
|
||||
ret = drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
|
||||
fb_id, x, y, output_ids, output_count, &kmode);
|
||||
if (ret)
|
||||
fb_id, x, y, output_ids, output_count,
|
||||
&drmmode_crtc->kmode);
|
||||
if (ret) {
|
||||
xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
|
||||
"failed to set mode: %s", strerror(-ret));
|
||||
else
|
||||
ret = FALSE;
|
||||
} else
|
||||
ret = TRUE;
|
||||
|
||||
/* Turn on any outputs on this crtc that may have been disabled */
|
||||
|
|
@ -406,7 +377,52 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
|
|||
|
||||
if (scrn->pScreen)
|
||||
xf86_reload_cursors(scrn->pScreen);
|
||||
|
||||
return ret;
|
||||
|
||||
done:
|
||||
free(output_ids);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
|
||||
Rotation rotation, int x, int y)
|
||||
{
|
||||
ScrnInfoPtr scrn = crtc->scrn;
|
||||
intel_screen_private *intel = intel_get_screen_private(scrn);
|
||||
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||
drmmode_ptr drmmode = drmmode_crtc->drmmode;
|
||||
int saved_x, saved_y;
|
||||
Rotation saved_rotation;
|
||||
DisplayModeRec saved_mode;
|
||||
int ret = TRUE;
|
||||
unsigned int pitch = scrn->displayWidth * intel->cpp;
|
||||
|
||||
if (drmmode->fb_id == 0) {
|
||||
ret = drmModeAddFB(drmmode->fd,
|
||||
scrn->virtualX, scrn->virtualY,
|
||||
scrn->depth, scrn->bitsPerPixel,
|
||||
pitch, intel->front_buffer->handle,
|
||||
&drmmode->fb_id);
|
||||
if (ret < 0) {
|
||||
ErrorF("failed to add fb\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
saved_mode = crtc->mode;
|
||||
saved_x = crtc->x;
|
||||
saved_y = crtc->y;
|
||||
saved_rotation = crtc->rotation;
|
||||
|
||||
crtc->mode = *mode;
|
||||
crtc->x = x;
|
||||
crtc->y = y;
|
||||
crtc->rotation = rotation;
|
||||
|
||||
drmmode_ConvertToKMode(crtc->scrn, &drmmode_crtc->kmode, mode);
|
||||
ret = drmmode_apply(crtc);
|
||||
if (!ret) {
|
||||
crtc->x = saved_x;
|
||||
crtc->y = saved_y;
|
||||
|
|
@ -1296,8 +1312,8 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
|
|||
if (!crtc->enabled)
|
||||
continue;
|
||||
|
||||
drmmode_set_mode_major(crtc, &crtc->mode,
|
||||
crtc->rotation, crtc->x, crtc->y);
|
||||
if (!drmmode_apply(crtc))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (old_fb_id)
|
||||
|
|
|
|||
Loading…
Reference in New Issue