Hi,

Cross-posting to openssh-unix-dev and xorg-devel because this concerns both 
projects.

When X11 connection is forwarded using ssh, the ssh client typically connects 
to the local X server using unix socket (often it is the only option because X 
servers no longer listens on TCP by default). X clients connected remotely 
over ssh then seem like if they are local to the X server. Because of that it 
will attempt to use extensions that are meant for local clients only (SHM, 
DRI*, etc). In most cases the client or server can detect failure and fallback 
to a method that works remotely, but this does not always work:

https://bugzilla.opensuse.org/show_bug.cgi?id=1022727
(comments 24-26)

In case of DRI3, X server tries to pass file descriptor to the X client. That 
works over the unix socket between X server and SSH client, but of course can 
not be sent further over network. There is no way failure can be detected and 
the communication gets stuck forever.

The ideal solution would be if ssh marked the connection as remote.
X protocol supports that since 2011:
https://cgit.freedesktop.org/xorg/xserver/commit/?
id=e2c7d70e5ddb8b17676a13ceebfbb87d14d63243

SSH only needs to change the first byte sent from X client to server to mark 
it as remote. SSH already modifies the whole first message (replaces 
authorization data), so changing the first byte is easy addition.

I have attached patch that implements it. Please check it and consider adding 
it or something similar to openssh.

Best regards,
Michal Srb
>From 0ab799d99113fd20e918fb2bc740614ce8388dcb Mon Sep 17 00:00:00 2001
From: Michal Srb <m...@suse.com>
Date: Mon, 21 Aug 2017 15:49:38 +0200
Subject: [PATCH] Mark x11 connection as remote.

If we are channeling x11 connection, modify the byte order field to let
X server know that the connection is remote.
---
 channels.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/channels.c b/channels.c
index 028d5db2..2a09f91a 100644
--- a/channels.c
+++ b/channels.c
@@ -931,10 +931,12 @@ x11_open_helper(Buffer *b)
 
 	/* Parse the lengths of variable-length fields. */
 	ucp = buffer_ptr(b);
-	if (ucp[0] == 0x42) {	/* Byte order MSB first. */
+	if (ucp[0] == 0x42 || ucp[0] == 0x52) {	/* Byte order MSB first. */
+		ucp[0] = 0x52;	/* MSB first + remote connection flag */
 		proto_len = 256 * ucp[6] + ucp[7];
 		data_len = 256 * ucp[8] + ucp[9];
-	} else if (ucp[0] == 0x6c) {	/* Byte order LSB first. */
+	} else if (ucp[0] == 0x6c || ucp[0] == 0x72) {	/* Byte order LSB first. */
+		ucp[0] = 0x72;	/* LSB first + remote connection flag */
 		proto_len = ucp[6] + 256 * ucp[7];
 		data_len = ucp[8] + 256 * ucp[9];
 	} else {
-- 
2.12.3

_______________________________________________
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to