<div dir="ltr">I was just reading the source when I found it (no valgrind involved). So as wl_connection_destroy() already takes care of that, my patch is pointless.<div><br></div><div>My final idea would be to add support to fds that have the F_SEAL_SHRINK seal set (see memfd_create(2) and fcntl(2)), so if a client creates shm_pool with the shrink seal set, and the fd size (fstat(2)) is already >= size arg passed to wl_shm_create_pool, we no longer would need to set SIGBUS handlers when the compositor needs to access that shm memory.</div><div>Does this make any sense/would be a good idea?</div><div class="gmail_extra"><br><div class="gmail_quote">2016-02-19 2:49 GMT+01:00 Jonas Ådahl <span dir="ltr"><<a href="mailto:jadahl@gmail.com" target="_blank">jadahl@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Thu, Feb 18, 2016 at 11:59:29PM +0100, Sergi Granell wrote:<br>
> If the client passed a size <= 0 to shm_create_pool, it would<br>
> go to err_free, which wouldn't close the fd, and thus leave it opened.<br>
><br>
> We can also move the size check before the struct wl_shm_pool<br>
> malloc, so in case the client passes a wrong size, it won't<br>
> do an unnecessary malloc and then free.<br>
<br>
</span>Did you detect this using valgrind or something like that? Because IIRC,<br>
we collect all transmitted file descriptors and close them when the<br>
client is destroyed (see wl_connection_destory()). Since we post an<br>
error, the client will eventually be destroyed, so we shouldn't leak<br>
the fd here already.<br>
<br>
<br>
Jonas<br>
<div><div class="h5"><br>
> ---<br>
>  src/wayland-shm.c | 20 ++++++++++----------<br>
>  1 file changed, 10 insertions(+), 10 deletions(-)<br>
><br>
> diff --git a/src/wayland-shm.c b/src/wayland-shm.c<br>
> index a4343a4..81bf657 100644<br>
> --- a/src/wayland-shm.c<br>
> +++ b/src/wayland-shm.c<br>
> @@ -230,17 +230,17 @@ shm_create_pool(struct wl_client *client, struct wl_resource *resource,<br>
>  {<br>
>       struct wl_shm_pool *pool;<br>
><br>
> -     pool = malloc(sizeof *pool);<br>
> -     if (pool == NULL) {<br>
> -             wl_client_post_no_memory(client);<br>
> -             goto err_close;<br>
> -     }<br>
> -<br>
>       if (size <= 0) {<br>
>               wl_resource_post_error(resource,<br>
>                                      WL_SHM_ERROR_INVALID_STRIDE,<br>
>                                      "invalid size (%d)", size);<br>
> -             goto err_free;<br>
> +             goto err_close;<br>
> +     }<br>
> +<br>
> +     pool = malloc(sizeof *pool);<br>
> +     if (pool == NULL) {<br>
> +             wl_client_post_no_memory(client);<br>
> +             goto err_close;<br>
>       }<br>
><br>
>       pool->refcount = 1;<br>
> @@ -251,7 +251,7 @@ shm_create_pool(struct wl_client *client, struct wl_resource *resource,<br>
>               wl_resource_post_error(resource,<br>
>                                      WL_SHM_ERROR_INVALID_FD,<br>
>                                      "failed mmap fd %d", fd);<br>
> -             goto err_close;<br>
> +             goto err_free;<br>
>       }<br>
>       close(fd);<br>
><br>
> @@ -270,10 +270,10 @@ shm_create_pool(struct wl_client *client, struct wl_resource *resource,<br>
><br>
>       return;<br>
><br>
> -err_close:<br>
> -     close(fd);<br>
>  err_free:<br>
>       free(pool);<br>
> +err_close:<br>
> +     close(fd);<br>
>  }<br>
><br>
>  static const struct wl_shm_interface shm_interface = {<br>
> --<br>
> 2.7.1<br>
><br>
</div></div>> _______________________________________________<br>
> wayland-devel mailing list<br>
> <a href="mailto:wayland-devel@lists.freedesktop.org">wayland-devel@lists.freedesktop.org</a><br>
> <a href="https://lists.freedesktop.org/mailman/listinfo/wayland-devel" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/wayland-devel</a><br>
</blockquote></div><br></div></div>