From e95bb97073ca77193e4c51bd1504403fbe245533 Mon Sep 17 00:00:00 2001 From: Colin Harrison Date: Tue, 25 Jun 2013 21:34:43 +0100 Subject: [PATCH] hw/xwin: Fix possible crash in winMultiWindowGetClassHint Fix a possible crash in winMultiWindowGetClassHint() when an application doesn't null terminate the WM_CLASS property class name (which is an ICCCM conformance bug in the application) (Reported for running the contiki cooja simulator in multiwindow mode, although it seems that many Java clients may have this problem, see [1]) Based on a patch by Marc Haesen. v2: Avoid using strnlen() which is missing on MinGW v3: Align with Xming patch [1] http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6961123 Signed-off-by: Colin Harrison Reviewed-by: Yaakov Selkowitz Reviewed-by: Jon TURNEY --- hw/xwin/winmultiwindowclass.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/hw/xwin/winmultiwindowclass.c b/hw/xwin/winmultiwindowclass.c index ced8f4554..6787332a3 100644 --- a/hw/xwin/winmultiwindowclass.c +++ b/hw/xwin/winmultiwindowclass.c @@ -68,7 +68,12 @@ winMultiWindowGetClassHint(WindowPtr pWin, char **res_name, char **res_class) while (prop) { if (prop->propertyName == XA_WM_CLASS && prop->type == XA_STRING && prop->format == 8 && prop->data) { + /* + WM_CLASS property should consist of 2 null terminated strings, but we + must handle the cases when one or both is absent or not null terminated + */ len_name = strlen((char *) prop->data); + if (len_name > prop->size) len_name = prop->size; (*res_name) = malloc(len_name + 1); @@ -77,13 +82,13 @@ winMultiWindowGetClassHint(WindowPtr pWin, char **res_name, char **res_class) return 0; } - /* Add one to len_name to allow copying of trailing 0 */ - strncpy((*res_name), prop->data, len_name + 1); + /* Copy name and ensure null terminated */ + strncpy((*res_name), prop->data, len_name); + (*res_name)[len_name] = '\0'; - if (len_name == prop->size) - len_name--; - - len_class = strlen(((char *) prop->data) + 1 + len_name); + /* Compute length of class name, it could be that it is absent or not null terminated */ + len_class = (len_name >= prop->size) ? 0 : (strlen(((char *) prop->data) + 1 + len_name)); + if (len_class > prop->size - 1 - len_name) len_class = prop->size - 1 - len_name; (*res_class) = malloc(len_class + 1); @@ -95,7 +100,9 @@ winMultiWindowGetClassHint(WindowPtr pWin, char **res_name, char **res_class) return 0; } - strcpy((*res_class), ((char *) prop->data) + 1 + len_name); + /* Copy class name and ensure null terminated */ + strncpy((*res_class), ((char *) prop->data) + 1 + len_name, len_class); + (*res_class)[len_class] = '\0'; return 1; }