Discussion:
[Xcb] Question about a xcb_util.c commit
David Coppa
2016-06-10 14:30:34 UTC
Permalink
Hi all,

I have a question regarding this particular commit, "Fallback to
TCP if no protocol is specified and the UNIX connection fails",
that you can see at
https://cgit.freedesktop.org/xcb/libxcb/commit/?id=7d235c62f0d5bd0df1236cc52141c10c5d272a18

Does anyone know the rationale behind it?

It seems strange to me to try to connect via tcp if opening the
unix socket fails (because the X server crashed, for example).

I'm asking because this piece of code does not interact very well
with the way we're sandboxing some window managers (specifically
i3) using pledge() on OpenBSD.

When pledged, i3 is not allowed to open AF_INET sockets, only AF_UNIX
ones.

Cheers!
David
Uli Schlachter
2016-06-10 15:27:34 UTC
Permalink
Hi,
Post by David Coppa
Hi all,
I have a question regarding this particular commit, "Fallback to
TCP if no protocol is specified and the UNIX connection fails",
that you can see at
https://cgit.freedesktop.org/xcb/libxcb/commit/?id=7d235c62f0d5bd0df1236cc52141c10c5d272a18
Does anyone know the rationale behind it?
Not really, but if you want me to guess: No protocol specified can be
interpreted as a wildcard, so why not try both?
Post by David Coppa
It seems strange to me to try to connect via tcp if opening the
unix socket fails (because the X server crashed, for example).
How about "the X server only listens on TCP and that's why the unix socket
didn't work"?
Post by David Coppa
I'm asking because this piece of code does not interact very well
with the way we're sandboxing some window managers (specifically
i3) using pledge() on OpenBSD.
When pledged, i3 is not allowed to open AF_INET sockets, only AF_UNIX
ones.
Ok, so what is the problem here?

Scenario 1: X server listens on the unix socket. XCB connects to the unix socket
and everything works.

Scenario 2: No X server running. The unix socket fails (because nothing listens
on it), the TCP socket fails (permission denied, I guess). An error is reported.

Also: When exactly does i3 pledge()? Does this break e.g. "DISPLAY=1.2.3.4:0
i3"? I thought people were "angry" about wayland because it isn't as (pseudo)
network transparent as X11.

Uli
--
Bitte nicht mit dem verbleibenden Auge in den Laser gucken.
- Vincent Ebert
David Coppa
2016-06-10 16:34:26 UTC
Permalink
Post by David Coppa
Hi,
Post by David Coppa
Hi all,
I have a question regarding this particular commit, "Fallback to
TCP if no protocol is specified and the UNIX connection fails",
that you can see at
https://cgit.freedesktop.org/xcb/libxcb/commit/?id=7d235c62f0d5bd0df1236cc52141c10c5d272a18
Post by David Coppa
Does anyone know the rationale behind it?
Not really, but if you want me to guess: No protocol specified can be
interpreted as a wildcard, so why not try both?
Post by David Coppa
It seems strange to me to try to connect via tcp if opening the
unix socket fails (because the X server crashed, for example).
How about "the X server only listens on TCP and that's why the unix socket
didn't work"?
Post by David Coppa
I'm asking because this piece of code does not interact very well
with the way we're sandboxing some window managers (specifically
i3) using pledge() on OpenBSD.
When pledged, i3 is not allowed to open AF_INET sockets, only AF_UNIX
ones.
Ok, so what is the problem here?
Scenario 1: X server listens on the unix socket. XCB connects to the unix socket
and everything works.
Scenario 2: No X server running. The unix socket fails (because nothing listens
on it), the TCP socket fails (permission denied, I guess). An error is reported.
Also: When exactly does i3 pledge()? Does this break e.g.
"DISPLAY=1.2.3.4:0
i3"? I thought people were "angry" about wayland because it isn't as (pseudo)
network transparent as X11
Yes, running a pledged i3 on a remote X server is not possible, because "inet" has not been declared in the allowed pledges. I think it's an acceptable compromise, and Xorg by default runs with 'nolisten tcp' btw, iirc...

Mine it's not really a problem, my question was mainly driven by curiosity.

We had a report by a user some time ago about i3 dumping core, after an X server crash, with a pledge related message:

i3(49392): syscall 97 "inet"

The X crash was caused by a bug in the radeon driver, while i3 was killed by the pledge subsystem because of restore_xcb_check_cb() (src/restore_layout.c). If it sees that the
connection to X has been lost, it calls restore_connect() which calls
libxcb's xcb_connect().
In libxcb that calls xcb_connect_to_display_with_auth_info() which calls
_xcb_open(), which calls _xcb_open_unix() and ususally that would be it,
but if opening the unix socket fails (beause X has fallen over) it tries
again to connect by calling _xcb_open_tcp() which sets up an AF_INET addrinfo and passes that to _xcb_socket().

Thanks for your insights!
David
Uli Schlachter
2016-06-10 16:51:04 UTC
Permalink
Am 10.06.2016 um 18:34 schrieb David Coppa:
[...]
Post by David Coppa
Post by Uli Schlachter
Also: When exactly does i3 pledge()? Does this break e.g.
"DISPLAY=1.2.3.4:0
i3"? I thought people were "angry" about wayland because it isn't as (pseudo)
network transparent as X11
Yes, running a pledged i3 on a remote X server is not possible, because "inet" has not been declared in the allowed pledges. I think it's an acceptable compromise, and Xorg by default runs with 'nolisten tcp' btw, iirc...
Mine it's not really a problem, my question was mainly driven by curiosity.
i3(49392): syscall 97 "inet"
The X crash was caused by a bug in the radeon driver, while i3 was killed by the pledge subsystem because of restore_xcb_check_cb() (src/restore_layout.c). If it sees that the
connection to X has been lost, it calls restore_connect() which calls
libxcb's xcb_connect().
In libxcb that calls xcb_connect_to_display_with_auth_info() which calls
_xcb_open(), which calls _xcb_open_unix() and ususally that would be it,
but if opening the unix socket fails (beause X has fallen over) it tries
again to connect by calling _xcb_open_tcp() which sets up an AF_INET addrinfo and passes that to _xcb_socket().
Ah. I neither knew that i3 can survive the X11 connection breaking nor that
pledge() aborts the program instead of making operations fail.

A "weird work-around" that comes to my mind would be to replace conn =
xcb_connect(NULL, &conn_screen); with something like the following (but without
the obvious overflow issues):

char buffer[42];
const char *display = getenv("DISPLAY");
/* Force protocol to be "unix" if no protocol is specified to disable TCP
attempts which pledge() would catch */
if (display != NULL && strchr(display, '/')) {
sprintf(buffer, "unix/%s", display);
display = buffer;
}
conn = xcb_connect(display, &conn_screen);

Cheers,
Uli
--
- Buck, when, exactly, did you lose your mind?
- Three months ago. I woke up one morning married to a pineapple.
An ugly pineapple... But I loved her.
Josh Triplett
2016-06-10 16:50:42 UTC
Permalink
Post by David Coppa
I have a question regarding this particular commit, "Fallback to
TCP if no protocol is specified and the UNIX connection fails",
that you can see at
https://cgit.freedesktop.org/xcb/libxcb/commit/?id=7d235c62f0d5bd0df1236cc52141c10c5d272a18
Does anyone know the rationale behind it?
Compatibility with the historical behavior of Xlib. See
https://lists.x.org/archives/xorg-devel/2010-April/007915.html .

DISPLAY=:0 (or any :N) without a protocol specified means to try a UNIX
socket and then TCP.
Post by David Coppa
It seems strange to me to try to connect via tcp if opening the
unix socket fails (because the X server crashed, for example).
I'm asking because this piece of code does not interact very well
with the way we're sandboxing some window managers (specifically
i3) using pledge() on OpenBSD.
When pledged, i3 is not allowed to open AF_INET sockets, only AF_UNIX
ones.
If your default configuration has the X server listening only on a unix
socket, I would suggest having your default configuration set
DISPLAY=unix/:0 rather than DISPLAY=:0. Then, applications will *only*
connect via UNIX socket, and never fall back to TCP.

I've reported a bug on xinit/startx to have them do this by default:
https://bugs.freedesktop.org/show_bug.cgi?id=96483

- Josh Triplett
Alan Coopersmith
2016-06-10 16:58:15 UTC
Permalink
Post by Josh Triplett
Post by David Coppa
I have a question regarding this particular commit, "Fallback to
TCP if no protocol is specified and the UNIX connection fails",
that you can see at
https://cgit.freedesktop.org/xcb/libxcb/commit/?id=7d235c62f0d5bd0df1236cc52141c10c5d272a18
Does anyone know the rationale behind it?
Compatibility with the historical behavior of Xlib. See
https://lists.x.org/archives/xorg-devel/2010-April/007915.html .
DISPLAY=:0 (or any :N) without a protocol specified means to try a UNIX
socket and then TCP.
Which I think was needed in the past for proxies like ssh & xscope that only
opened TCP sockets rather than baking in knowledge of the Unix domain socket
paths that X used but weren't formally specified.
--
-Alan Coopersmith- ***@oracle.com
Oracle Solaris Engineering - http://blogs.oracle.com/alanc
Loading...