From 8fd13a52072c2f8f12f934deaba1ef9ddb16d5f9 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 5 May 2014 09:32:59 +0100 Subject: [PATCH] sna: Reorder connector initialisation to avoid leak If the output was ignored, we would leak the allocations. However, we can check the output name after the first GETCONNECTOR/GETENCODER request before any allocations. Signed-off-by: Chris Wilson --- src/sna/sna_display.c | 64 +++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index ed3b9b0d..e46f5d15 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -2723,7 +2723,7 @@ sna_output_add(struct sna *sna, int id, drmModeResPtr res, int serial) xf86OutputPtr *outputs, output; const char *output_name; char name[32]; - int len, i, ret = -1; + int len, i; DBG(("%s(%d)\n", __FUNCTION__, id)); @@ -2750,11 +2750,41 @@ sna_output_add(struct sna *sna, int id, drmModeResPtr res, int serial) return 0; } + if (compat_conn.conn.connector_type < ARRAY_SIZE(output_names)) + output_name = output_names[compat_conn.conn.connector_type]; + else + output_name = "UNKNOWN"; + len = snprintf(name, 32, "%s%d", output_name, compat_conn.conn.connector_type_id); + if (output_ignored(scrn, name)) + return 0; + if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETENCODER, &enc)) { DBG(("%s: GETENCODER failed, ret=%d\n", __FUNCTION__, errno)); return 0; } + if (xf86IsEntityShared(scrn->entityList[0])) { + const char *str; + + str = xf86GetOptValString(sna->Options, OPTION_ZAPHOD); + if (str && !sna_zaphod_match(str, name)) { + DBG(("%s: zaphod mismatch, want %s, have %s\n", __FUNCTION__, str, name)); + return 0; + } + + if ((enc.possible_crtcs & (1 << scrn->confScreen->device->screen)) == 0) { + if (str) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "%s is an invalid output for screen (pipe) %d\n", + name, scrn->confScreen->device->screen); + return -1; + } else + return 0; + } + + enc.possible_crtcs = 1; + } + sna_output = calloc(sizeof(struct sna_output), 1); if (!sna_output) return -1; @@ -2783,36 +2813,6 @@ sna_output_add(struct sna *sna, int id, drmModeResPtr res, int serial) VG(VALGRIND_MAKE_MEM_DEFINED(sna_output->prop_ids, sizeof(uint32_t)*sna_output->num_props)); VG(VALGRIND_MAKE_MEM_DEFINED(sna_output->prop_values, sizeof(uint64_t)*sna_output->num_props)); - if (compat_conn.conn.connector_type < ARRAY_SIZE(output_names)) - output_name = output_names[compat_conn.conn.connector_type]; - else - output_name = "UNKNOWN"; - len = snprintf(name, 32, "%s%d", output_name, compat_conn.conn.connector_type_id); - if (output_ignored(scrn, name)) - return 0; - - if (xf86IsEntityShared(scrn->entityList[0])) { - const char *str; - - str = xf86GetOptValString(sna->Options, OPTION_ZAPHOD); - if (str && !sna_zaphod_match(str, name)) { - DBG(("%s: zaphod mismatch, want %s, have %s\n", __FUNCTION__, str, name)); - ret = 0; - goto cleanup; - } - - if ((enc.possible_crtcs & (1 << scrn->confScreen->device->screen)) == 0) { - if (str) { - xf86DrvMsg(scrn->scrnIndex, X_ERROR, - "%s is an invalid output for screen (pipe) %d\n", - name, scrn->confScreen->device->screen); - } - goto cleanup; - } - - enc.possible_crtcs = 1; - } - output = calloc(1, sizeof(*output) + len + 1); if (!output) goto cleanup; @@ -2889,7 +2889,7 @@ cleanup: free(sna_output->prop_ids); free(sna_output->prop_values); free(sna_output); - return ret; + return -1; } static void sna_output_del(xf86OutputPtr output)