This is actually a regression against openssh-4.1p1. Try: ssh -Y user@host "(sleep 5; xterm) &" After 5 seconds it will print: xterm Xt error: Can't open display: localhost:10.0 It will work fine on openssh-4.1p1 server.
It appears to be fallout from this change (channels.c rev 1.200 and session.c rev 1.302): - djm@cvs.openbsd.org 2005/07/17 06:49:04 [channels.c channels.h session.c session.h] Fix a number of X11 forwarding channel leaks: 1. Refuse multiple X11 forwarding requests on the same session 2. Clean up all listeners after a single_connection X11 forward, not just the one that made the single connection 3. Destroy X11 listeners when the session owning them goes away testing and ok dtucker@ It's probably (3) since the "()&" causes the child of sshd to exit immediately. Maybe it needs to wait until the session close completes before destroying the X11 listeners?
hm, this is tricky: the /session/ is closed immediately upon child exit, but the /channel/ persists after this time (until read EOF or error). The X11 listeners need to be shut down when the /channel/ goes away, but we don't have any way to mark the listeners as dependant on the channel. The choices are: 1. Move x11_chanids from "struct Session" into "struct Channel", so we can deallocate them with a cleanup function. (ugly layering violation, but we already have several of these) 2. Don't session_close() a session until its undelying channel goes away entirely. This may be a good way to do it - just don't deallocate the channel in session_exit_message(), instead let the channel close callback take care of it (include X11 closure) 3. Make all sessions share a single X11 listener. This could be simple, but it would move us further away from supporting multiple X11 forwarding in the future (if we ever chose to do it)
4. Continue tracking the x11_chanids in session.c in a separate structure to the session and detach them using a channel callback registered after the normal one is detached in session_exit_message() (the obvious approach [2] turns out not to work for reasons that aren't entirely clear to me).
Created attachment 964 [details] Probable fix This is approach #4, creating a new list of X11 channels and the session channels that they depend upon in session.c. Please test - we need tests of this particular bug, but also regress and general usage.
approach #2 didn't work because I wasn't able to arrange for the correct sequence of "send exit message, close session channel and then close dependent X11 channels" to occur. If anyone wants to try this, make sure you run the regression tests, particularly t-exit-status.sh
Created attachment 965 [details] Better patch This is a better (more simple) fix, making approach #2 work right.
Created attachment 967 [details] Improved fix This patch is better, it doesn't leak sessions after they are closed.
I've tested the patch from comment 7 and the reported problem is fixed. However it makes it fail the dynamic-forward.sh test. I haven't tried skipping it so I don't know if later test succeed.
I've forgot to put here the test output: run test dynamic-forward.sh ... Waiting for forwarded connections to terminate... The following connections are open: #1 direct-tcpip: listening port 4243 for 127.0.0.1 port 4242, connect from 127.0.0.1 port 35822 (t4 r3 i0/0 o3/0 fd 10/10 cfd -1) nc: unexpected reply size 31 (expected 10) ssh_exchange_identification: Connection closed by remote host cmp: EOF on /home/mraz/rhcvs/openssh/FC-4/openssh-4.2p1/regress/ls.copy corrupted copy of /bin/ls failed dynamic forwarding
I am sure that you are seeing a bug in nc that was fixed between OpenBSD 3.7 and 3.8. Could you try updating it and running the test again.
Actually it was a bug in a patch in Fedora Core 4 nc RPM package. After fixing it the patched openssh passes all tests fine.
Comment on attachment 967 [details] Improved fix Attachment id #967 looks and tests OK here.
Fix committed - will be in 4.3
Change all RESOLVED bug to CLOSED with the exception of the ones fixed post-4.4.