tk/Fix-502e74e9ad-crash-for-untrusted-X-connections-for.patch

141 lines
4.5 KiB
Diff
Raw Normal View History

2019-09-30 11:18:32 -04:00
From f0ac004c7b9eb1d05be53e4b764e81076d314c6f Mon Sep 17 00:00:00 2001
From: fvogel <fvogelnew1@free.fr>
Date: Mon, 29 Jan 2018 21:32:53 +0000
Subject: [PATCH 131/693] Fix [502e74e9ad]: crash for untrusted X connections
(for ssh: ForwardX11Trusted no). Patch from Christian Werner.
---
unix/tkUnixSend.c | 66 ++++++++++++++++++++++++++++++-----------------
1 file changed, 42 insertions(+), 24 deletions(-)
diff --git a/unix/tkUnixSend.c b/unix/tkUnixSend.c
index bbbdd774c..95e5ae27e 100644
--- a/unix/tkUnixSend.c
+++ b/unix/tkUnixSend.c
@@ -261,11 +261,14 @@ RegOpen(
unsigned long bytesAfter;
Atom actualType;
char **propertyPtr;
+ Tk_ErrorHandler handler;
if (dispPtr->commTkwin == NULL) {
SendInit(interp, dispPtr);
}
+ handler = Tk_CreateErrorHandler(dispPtr->display, -1, -1, -1, NULL, NULL);
+
regPtr = ckalloc(sizeof(NameRegistry));
regPtr->dispPtr = dispPtr;
regPtr->locked = 0;
@@ -306,8 +309,11 @@ RegOpen(
XDeleteProperty(dispPtr->display,
RootWindow(dispPtr->display, 0),
dispPtr->registryProperty);
+ XSync(dispPtr->display, False);
}
+ Tk_DeleteErrorHandler(handler);
+
/*
* Xlib placed an extra null byte after the end of the property, just to
* make sure that it is always NULL-terminated. Be sure to include this
@@ -514,6 +520,11 @@ RegClose(
NameRegistry *regPtr) /* Pointer to a registry opened with a
* previous call to RegOpen. */
{
+ Tk_ErrorHandler handler;
+
+ handler = Tk_CreateErrorHandler(regPtr->dispPtr->display, -1, -1, -1,
+ NULL, NULL);
+
if (regPtr->modified) {
if (!regPtr->locked && !localData.sendDebug) {
Tcl_Panic("The name registry was modified without being locked!");
@@ -540,6 +551,8 @@ RegClose(
XFlush(regPtr->dispPtr->display);
+ Tk_DeleteErrorHandler(handler);
+
if (regPtr->property != NULL) {
if (regPtr->allocedByX) {
XFree(regPtr->property);
@@ -1095,6 +1108,31 @@ Tk_SendObjCmd(
Tcl_DStringAppend(&request, " ", 1);
Tcl_DStringAppend(&request, Tcl_GetString(objv[i]), -1);
}
+
+ if (!async) {
+ /*
+ * Register the fact that we're waiting for a command to complete
+ * (this is needed by SendEventProc and by AppendErrorProc to pass
+ * back the command's results). Set up a timeout handler so that
+ * we can check during long sends to make sure that the destination
+ * application is still alive.
+ *
+ * We prepare the pending struct here in order to catch potential
+ * early X errors from AppendPropCarefully() due to XSync().
+ */
+
+ pending.serial = localData.sendSerial;
+ pending.dispPtr = dispPtr;
+ pending.target = destName;
+ pending.commWindow = commWindow;
+ pending.interp = interp;
+ pending.result = NULL;
+ pending.errorInfo = NULL;
+ pending.errorCode = NULL;
+ pending.gotResponse = 0;
+ pending.nextPtr = tsdPtr->pendingCommands;
+ tsdPtr->pendingCommands = &pending;
+ }
(void) AppendPropCarefully(dispPtr->display, commWindow,
dispPtr->commProperty, Tcl_DStringValue(&request),
Tcl_DStringLength(&request) + 1, (async ? NULL : &pending));
@@ -1108,26 +1146,6 @@ Tk_SendObjCmd(
return TCL_OK;
}
- /*
- * Register the fact that we're waiting for a command to complete (this is
- * needed by SendEventProc and by AppendErrorProc to pass back the
- * command's results). Set up a timeout handler so that we can check
- * during long sends to make sure that the destination application is
- * still alive.
- */
-
- pending.serial = localData.sendSerial;
- pending.dispPtr = dispPtr;
- pending.target = destName;
- pending.commWindow = commWindow;
- pending.interp = interp;
- pending.result = NULL;
- pending.errorInfo = NULL;
- pending.errorCode = NULL;
- pending.gotResponse = 0;
- pending.nextPtr = tsdPtr->pendingCommands;
- tsdPtr->pendingCommands = &pending;
-
/*
* Enter a loop processing X events until the result comes in or the
* target is declared to be dead. While waiting for a result, look only at
@@ -1959,11 +1977,11 @@ TkpTestsendCmd(
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObjStruct(interp, objv[1], testsendOptions,
+ if (Tcl_GetIndexFromObjStruct(interp, objv[1], testsendOptions,
sizeof(char *), "option", 0, &index) != TCL_OK) {
- return TCL_ERROR;
- }
- if (index == TESTSEND_BOGUS) {
+ return TCL_ERROR;
+ }
+ if (index == TESTSEND_BOGUS) {
XChangeProperty(winPtr->dispPtr->display,
RootWindow(winPtr->dispPtr->display, 0),
winPtr->dispPtr->registryProperty, XA_INTEGER, 32,
--
2.19.1