<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 11, 2015 at 10:05 PM, Bryce Harrington <span dir="ltr"><<a href="mailto:bryce@osg.samsung.com" target="_blank">bryce@osg.samsung.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class=""><div class="h5">On Tue, Feb 24, 2015 at 03:08:36PM +0100, Davide Bettio wrote:<br>
> commit e8b37de8e084d4e50a12bd2911657d54c0ebd9ed<br>
> Author: Davide Bettio <<a href="mailto:davide.bettio@ispirata.com">davide.bettio@ispirata.com</a>><br>
> Date: Tue Feb 24 12:40:49 2015 +0100<br>
><br>
> * Extend WAYLAND_DISPLAY and name parameter semantics to support<br>
> absolute paths.<br>
> For example WAYLAND_DISPLAY="/my/path/wayland-2" or<br>
> connect_to_socket("/my/path/wayland-2").<br>
><br>
> * Introduce WAYLAND_SERVER_SOCKET_DIR to change socket directory<br>
> without changing XDG_RUNTIME_DIR.<br>
> This might be useful to change socket directory in case<br>
> wl_display_add_socket_auto is used.<br>
> For example this will change the socket path for weston without<br>
> using any command line argument.<br>
> This envvar is ignored when WAYLAND_SERVER_SOCKET is set to an<br>
> absolute path.<br>
><br>
> * Introduce WAYLAND_SERVER_SOCKET to change the path where the<br>
> server will create the socket.<br>
> It will be possible for a nested compositor to offer a socket<br>
> located in WAYLAND_SERVER_SOCKET path<br>
> while connecting to the main compositor socket that is located<br>
> in WAYLAND_DISPLAY path.<br>
> That's the reason why a futher WAYLAND_SERVER_SOCKET envvar has<br>
> been introduced.<br>
><br>
> Wayland clients will not see any new environment variable, while<br>
> compositors may have to deal<br>
> with 2 extra environment variables, this is due the fact that a<br>
> compositor might be a client of<br>
> another compositor and we must make sure that WAYLAND_DISPLAY is<br>
> not used for both client<br>
> and server purposes.<br>
><br>
> Signed-off-by: Davide Bettio <<a href="mailto:davide.bettio@ispirata.com">davide.bettio@ispirata.com</a>><br>
><br>
> diff --git a/doc/man/wl_display_connect.xml<br>
> b/doc/man/wl_display_connect.xml<br>
> index 7e6e05c..b78c53f 100644<br>
> --- a/doc/man/wl_display_connect.xml<br>
> +++ b/doc/man/wl_display_connect.xml<br>
> @@ -59,10 +59,10 @@<br>
> find it. The <varname>name</varname> argument specifies<br>
> the name of<br>
> the socket or <constant>NULL</constant> to use the<br>
> default (which is<br>
> <constant>"wayland-0"</constant>). The environment variable<br>
> - <envar>WAYLAND_DISPLAY</envar> replaces the default value. If<br>
> - <envar>WAYLAND_SOCKET</envar> is set, this function<br>
> behaves like<br>
> - <function>wl_display_connect_to_fd</function> with the<br>
> file-descriptor<br>
> - number taken from the environment variable.</para><br>
> + <envar>WAYLAND_DISPLAY</envar> replaces the default<br>
> value, and eventually uses<br>
> + a different path too. If <envar>WAYLAND_SOCKET</envar> is<br>
> set, this function<br>
> + behaves like<br>
> <function>wl_display_connect_to_fd</function> with the<br>
> + file-descriptor number taken from the environment<br>
> variable.</para><br>
><br>
> <para><function>wl_display_connect_to_fd</function> connects to<br>
> a Wayland<br>
> socket with an explicit file-descriptor. The<br>
> file-descriptor is passed<br>
> diff --git a/src/wayland-client.c b/src/wayland-client.c<br>
> index 0f1405c..cc01573 100644<br>
> --- a/src/wayland-client.c<br>
> +++ b/src/wayland-client.c<br>
> @@ -768,14 +768,26 @@ connect_to_socket(const char *name)<br>
><br>
> memset(&addr, 0, sizeof addr);<br>
> addr.sun_family = AF_LOCAL;<br>
> - name_size =<br>
> - snprintf(addr.sun_path, sizeof addr.sun_path,<br>
> - "%s/%s", runtime_dir, name) + 1;<br>
> + if (name[0] != '/') {<br>
> + name_size =<br>
> + snprintf(addr.sun_path, sizeof addr.sun_path,<br>
> + "%s/%s", runtime_dir, name) + 1;<br>
> + } else {<br>
> + /* absolute path */<br>
> + name_size =<br>
> + snprintf(addr.sun_path, sizeof addr.sun_path,<br>
> + "%s", name) + 1;<br>
> + }<br>
><br>
> assert(name_size > 0);<br>
> if (name_size > (int)sizeof addr.sun_path) {<br>
> - wl_log("error: socket path \"%s/%s\" plus null terminator"<br>
> - " exceeds 108 bytes\n", runtime_dir, name);<br>
> + if (name[0] != '/') {<br>
> + wl_log("error: socket path \"%s/%s\" plus null terminator"<br>
> + " exceeds 108 bytes\n", runtime_dir, name);<br>
> + } else {<br>
> + wl_log("error: socket path \"%s\" plus null terminator"<br>
> + " exceeds 108 bytes\n", name);<br>
> + }<br>
<br>
</div></div>Perhaps instead of the 108 magic number in the log message, print the<br>
actual numerical value of (int)sizeof addr.sun_path ?<br>
<span class=""><br>
> close(fd);<br>
> /* to prevent programs reporting<br>
> * "failed to add socket: Success" */<br>
> diff --git a/src/wayland-server.c b/src/wayland-server.c<br>
> index 0558634..39ba13f 100644<br>
> --- a/src/wayland-server.c<br>
> +++ b/src/wayland-server.c<br>
> @@ -1093,9 +1093,12 @@ wl_socket_init_for_display_name(struct<br>
> wl_socket *s, const char *name)<br>
> int name_size;<br>
> const char *runtime_dir;<br>
><br>
> - runtime_dir = getenv("XDG_RUNTIME_DIR");<br>
> + runtime_dir = getenv("WAYLAND_SERVER_SOCKET_DIR");<br>
> if (!runtime_dir) {<br>
> - wl_log("error: XDG_RUNTIME_DIR not set in the environment\n");<br>
> + runtime_dir = getenv("XDG_RUNTIME_DIR");<br>
> + }<br>
> + if (!runtime_dir) {<br>
> + wl_log("error: XDG_RUNTIME_DIR or WAYLAND_SERVER_SOCKET_DIR not<br>
> set in the environment\n");<br>
<br>
</span>Maybe reword this to avoid any ambiguity:<br>
<br>
wl_log("error: Neither XDG_RUNTIME_DIR nor WAYLAND_SERVER_SOCKET_DIR have been<br>
<span class="">set in the environment\n");<br>
<br>
</span>Or, perhaps less passively:<br>
<br>
wl_log("error: Either XDG_RUNTIME_DIR or WAYLAND_SERVER_SOCKET_DIR must be<br>
<span class="">set in the environment\n");<br>
<br>
> /* to prevent programs reporting<br>
> * "failed to add socket: Success" */<br>
> @@ -1104,15 +1107,28 @@ wl_socket_init_for_display_name(struct<br>
> wl_socket *s, const char *name)<br>
> }<br>
><br>
> s->addr.sun_family = AF_LOCAL;<br>
> - name_size = snprintf(s->addr.sun_path, sizeof s->addr.sun_path,<br>
> - "%s/%s", runtime_dir, name) + 1;<br>
> + if (name[0] != '/') {<br>
> + name_size = snprintf(s->addr.sun_path, sizeof s->addr.sun_path,<br>
> + "%s/%s", runtime_dir, name) + 1;<br>
> +<br>
> + s->display_name = (s->addr.sun_path + name_size - 1) - strlen(name);<br>
<br>
</span>I know this is the original code, and I'm probably missing something, but...<br>
If runtime_dir is of length N, and s->addr.sun_path is let's say 2N, and<br>
name is length 8N, then name_size = 2N+1, and only the first N-1 chars are<br>
used from name. I might be off by 1 or 2.<br>
<br>
But, now we have<br>
<br>
s->display_name = (2N + 2N + 1) - 8N = -4N + 1<br>
<br>
Do we have a buffer underflow possibility here?<br></blockquote><div><br></div>Actually, this will work, but the code is not correct. snprintf returns number of characters that it would have written if it had enough of space available (if it returns number < sizeof s->addr.sun_path everything is ok). So when name is of length 8N, then name_size is 8N + N + 1, and thus we have 8N + N + 1 - 1 - 8N = N which is the end of xdg_runtime string - therefore the display_name will point to add.sun_path and it will be valid pointer. Problem is that the name can be truncated, so we should check for the result of snprintf in any case.<br><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
In any case, may as well check for error return from snprintf<br>
(i.e. name_size < 0).<br>
<span class=""><br>
> + } else {<br>
> + //absolute path<br>
> + name_size = snprintf(s->addr.sun_path, sizeof s->addr.sun_path,<br>
> + "%s", name) + 1;<br>
><br>
> - s->display_name = (s->addr.sun_path + name_size - 1) - strlen(name);<br>
> + s->display_name = strrchr(s->addr.sun_path, '/') + 1;<br>
> + }<br>
><br>
> assert(name_size > 0);<br>
> if (name_size > (int)sizeof s->addr.sun_path) {<br>
> - wl_log("error: socket path \"%s/%s\" plus null terminator"<br>
> - " exceeds 108 bytes\n", runtime_dir, name);<br>
> + if (name[0] != '/') {<br>
> + wl_log("error: socket path \"%s/%s\" plus null terminator"<br>
> + " exceeds 108 bytes\n", runtime_dir,<br>
> name);<br>
> + } else {<br>
> + wl_log("error: socket path \"%s\" plus null terminator"<br>
> + " exceeds 108 bytes\n", name);<br>
> + }<br>
<br>
</span>108's here too.<br>
<div><div class="h5"><br>
> *s->addr.sun_path = 0;<br>
> /* to prevent programs reporting<br>
> * "failed to add socket: Success" */<br>
> @@ -1203,18 +1219,18 @@ wl_display_add_socket_auto(struct wl_display<br>
> *display)<br>
> * This adds a Unix socket to Wayland display which can be used by<br>
> clients to<br>
> * connect to Wayland display.<br>
> *<br>
> - * If NULL is passed as name, then it would look for<br>
> WAYLAND_DISPLAY env<br>
> - * variable for the socket name. If WAYLAND_DISPLAY is not set,<br>
> then default<br>
> - * wayland-0 is used.<br>
> + * If NULL is passed as name, then it would look in order for<br>
> WAYLAND_SERVER_SOCKET<br>
> + * and WAYLAND_SERVER env variable for the socket name. If<br>
> WAYLAND_DISPLAY and<br>
> + * WAYLAND_SERVER_SOCKET are not set, then default wayland-0 is used.<br>
> *<br>
> - * The Unix socket will be created in the directory pointed to by<br>
> environment<br>
> - * variable XDG_RUNTIME_DIR. If XDG_RUNTIME_DIR is not set, then<br>
> this function<br>
> - * fails and returns -1.<br>
> + * The Unix socket will be created in the directory pointed to by<br>
> either environment<br>
> + * variable WAYLAND_SERVER_SOCKET_DIR or XDG_RUNTIME_DIR. If the<br>
> none of the is set,<br>
> + * then this function fails and returns -1.<br>
> *<br>
> - * The length of socket path, i.e., the path set in XDG_RUNTIME_DIR<br>
> and the<br>
> + * The length of socket path, e.g., the path set in XDG_RUNTIME_DIR<br>
> and the<br>
> * socket name, must not exceed the maxium length of a Unix socket<br>
> path.<br>
> * The function also fails if the user do not have write permission<br>
> in the<br>
> - * XDG_RUNTIME_DIR path or if the socket name is already in use.<br>
> + * wayland socket path or if the socket name is already in use.<br>
> *<br>
> * \memberof wl_display<br>
> */<br>
> @@ -1228,6 +1244,8 @@ wl_display_add_socket(struct wl_display<br>
> *display, const char *name)<br>
> return -1;<br>
><br>
> if (name == NULL)<br>
> + name = getenv("WAYLAND_SERVER_SOCKET");<br>
> + if (name == NULL)<br>
> name = getenv("WAYLAND_DISPLAY");<br>
> if (name == NULL)<br>
> name = "wayland-0";<br>
<br>
</div></div>Aside from that, ditto daniel's review feedback.<br>
<div class=""><div class="h5"><br>
><br>
> _______________________________________________<br>
> wayland-devel mailing list<br>
> <a href="mailto:wayland-devel@lists.freedesktop.org">wayland-devel@lists.freedesktop.org</a><br>
> <a href="http://lists.freedesktop.org/mailman/listinfo/wayland-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/wayland-devel</a><br>
_______________________________________________<br>
wayland-devel mailing list<br>
<a href="mailto:wayland-devel@lists.freedesktop.org">wayland-devel@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/wayland-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/wayland-devel</a><br>
</div></div></blockquote></div><br></div><div class="gmail_extra">We're reviewing this series in two threads, we should agree on one to not confuse others :)<br></div><div class="gmail_extra">The other is: <a href="http://patchwork.freedesktop.org/patch/43801/">http://patchwork.freedesktop.org/patch/43801/</a><br></div></div>