141 lines
4.5 KiB
Diff
141 lines
4.5 KiB
Diff
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
|
|
|