[PATCH v2] Flush the connection if we have to many marshaled fds

Kristian Hoegsberg hoegsberg at gmail.com
Sat Mar 10 13:03:51 PST 2012


On Fri, Mar 09, 2012 at 12:51:42PM +0200, Ander Conselvan de Oliveira wrote:
> The buffer used by wl_connection_data to receive a cmsg is 128 bytes
> long. This can hold at most 28 fds but when a cmsg is generated for
> sending the fds, there is no check for this limitation. The man page
> for recvmsg does not show any way of recovering from MSG_CTRUNC, that
> happens when the buffer supplied for cmsg is too short.
> 
> Fix this by flushing the data to be written instead of generating a
> cmsg buffer longer than the maximum.

That's a very nice fix, thank you Ander.  And thanks Pekka for the
feedback, this version is good to go.  Committed and pushed.

Kristian

> ---
> 
> Changes in v2:
>  - handle errors in wl_connection_data
>  - changed the wording of the commit msg
> 
> 
>  src/connection.c |   30 ++++++++++++++++++++++++++----
>  1 files changed, 26 insertions(+), 4 deletions(-)
> 
> diff --git a/src/connection.c b/src/connection.c
> index 1ea2418..fa01545 100644
> --- a/src/connection.c
> +++ b/src/connection.c
> @@ -56,9 +56,13 @@ struct wl_closure {
>  	uint32_t *start;
>  };
>  
> +#define MAX_FDS_OUT	28
> +#define CLEN		(CMSG_LEN(MAX_FDS_OUT * sizeof(int32_t)))
> +
>  struct wl_connection {
>  	struct wl_buffer in, out;
>  	struct wl_buffer fds_in, fds_out;
> +	int n_fds_out;
>  	int fd;
>  	void *data;
>  	wl_connection_update_func_t update;
> @@ -217,7 +221,7 @@ build_cmsg(struct wl_buffer *buffer, char *data, int *clen)
>  static void
>  close_fds(struct wl_buffer *buffer)
>  {
> -	int fds[32], i, count;
> +	int fds[MAX_FDS_OUT], i, count;
>  	size_t size;
>  
>  	size = buffer->head - buffer->tail;
> @@ -252,7 +256,7 @@ wl_connection_data(struct wl_connection *connection, uint32_t mask)
>  {
>  	struct iovec iov[2];
>  	struct msghdr msg;
> -	char cmsg[128];
> +	char cmsg[CLEN];
>  	int len, count, clen;
>  
>  	if (mask & WL_CONNECTION_WRITABLE) {
> @@ -389,6 +393,21 @@ wl_message_size_extra(const struct wl_message *message)
>  	return extra;
>  }
>  
> +static int
> +wl_connection_put_fd(struct wl_connection *connection, int32_t fd)
> +{
> +	if (connection->n_fds_out + 1 > MAX_FDS_OUT) {
> +		if (wl_connection_data(connection, WL_CONNECTION_WRITABLE))
> +			return -1;
> +		connection->n_fds_out = 0;
> +	}
> +
> +	wl_buffer_put(&connection->fds_out, &fd, sizeof fd);
> +	connection->n_fds_out++;
> +
> +	return 0;
> +}
> +
>  struct wl_closure *
>  wl_connection_vmarshal(struct wl_connection *connection,
>  		       struct wl_object *sender,
> @@ -510,8 +529,11 @@ wl_connection_vmarshal(struct wl_connection *connection,
>  				abort();
>  			}
>  			*fd_ptr = dup_fd;
> -			wl_buffer_put(&connection->fds_out,
> -				      &dup_fd, sizeof dup_fd);
> +			if (wl_connection_put_fd(connection, dup_fd)) {
> +				printf("request could not be mashaled: "
> +				       "can't send file descriptor");
> +				return NULL;
> +			}
>  			break;
>  		default:
>  			fprintf(stderr, "unhandled format code: '%c'\n",
> -- 
> 1.7.4.1
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list