<div dir="ltr"><br><div class="gmail_extra"><div class="gmail_quote">On Thu, Apr 17, 2014 at 11:20 AM, Ander Conselvan de Oliveira <span dir="ltr"><<a href="mailto:conselvan2@gmail.com" target="_blank">conselvan2@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Ander Conselvan de Oliveira <<a href="mailto:ander.conselvan.de.oliveira@intel.com">ander.conselvan.de.oliveira@intel.com</a>><br>

<br>
If a message was too big to fit in the connection buffer, the code<br>
in wl_buffer_put would just write past the end of it.<br>
<br>
I haven't seen any real world use case that would trigger this bug, but<br>
it was possible to trigger it by sending a long enough string to the<br>
wl_data_source.offer request.<br></blockquote><div><br></div><div>This will flat out kill the client, no? It seems like we should be able to handle that more gracefully; does the client have any idea what the buffer size is?<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<a href="https://bugs.freedesktop.org/show_bug.cgi?id=69267" target="_blank">https://bugs.freedesktop.org/show_bug.cgi?id=69267</a><br>
---<br>
 src/connection.c        | 25 +++++++++++++++++--------<br>
 tests/connection-test.c | 37 +++++++++++++++++++++++++++++++++++++<br>
 2 files changed, 54 insertions(+), 8 deletions(-)<br>
<br>
diff --git a/src/connection.c b/src/connection.c<br>
index 40a2182..63b0592 100644<br>
--- a/src/connection.c<br>
+++ b/src/connection.c<br>
@@ -61,11 +61,18 @@ struct wl_connection {<br>
        int want_flush;<br>
 };<br>
<br>
-static void<br>
+static int<br>
 wl_buffer_put(struct wl_buffer *b, const void *data, size_t count)<br>
 {<br>
        uint32_t head, size;<br>
<br>
+       if (count > sizeof(b->data)) {<br>
+               wl_log("Data too big for buffer (%d > %d).\n",<br>
+                      count, sizeof(b->data));<br>
+               errno = E2BIG;<br>
+               return -1;<br>
+       }<br>
+<br>
        head = MASK(b->head);<br>
        if (head + count <= sizeof b->data) {<br>
                memcpy(b->data + head, data, count);<br>
@@ -76,6 +83,8 @@ wl_buffer_put(struct wl_buffer *b, const void *data, size_t count)<br>
        }<br>
<br>
        b->head += count;<br>
+<br>
+       return 0;<br>
 }<br>
<br>
 static void<br>
@@ -243,8 +252,8 @@ decode_cmsg(struct wl_buffer *buffer, struct msghdr *msg)<br>
                        size /= sizeof(int32_t);<br>
                        for (i = 0; i < size; i++)<br>
                                close(((int*)CMSG_DATA(cmsg))[i]);<br>
-               } else {<br>
-                       wl_buffer_put(buffer, CMSG_DATA(cmsg), size);<br>
+               } else if (wl_buffer_put(buffer, CMSG_DATA(cmsg), size) < 0) {<br>
+                               return -1;<br>
                }<br>
        }<br>
<br>
@@ -350,7 +359,9 @@ wl_connection_write(struct wl_connection *connection,<br>
                        return -1;<br>
        }<br>
<br>
-       wl_buffer_put(&connection->out, data, count);<br>
+       if (wl_buffer_put(&connection->out, data, count) < 0)<br>
+               return -1;<br>
+<br>
        connection->want_flush = 1;<br>
<br>
        return 0;<br>
@@ -367,7 +378,7 @@ wl_connection_queue(struct wl_connection *connection,<br>
                        return -1;<br>
        }<br>
<br>
-       wl_buffer_put(&connection->out, data, count);<br>
+       return wl_buffer_put(&connection->out, data, count);<br>
<br>
        return 0;<br></blockquote><div><br></div><div>You forgot to remove the "return 0;" here.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

 }<br>
@@ -394,9 +405,7 @@ wl_connection_put_fd(struct wl_connection *connection, int32_t fd)<br>
                        return -1;<br>
        }<br>
<br>
-       wl_buffer_put(&connection->fds_out, &fd, sizeof fd);<br>
-<br>
-       return 0;<br>
+       return wl_buffer_put(&connection->fds_out, &fd, sizeof fd);<br>
 }<br>
<br>
 const char *<br>
diff --git a/tests/connection-test.c b/tests/connection-test.c<br>
index 52d235d..1213875 100644<br>
--- a/tests/connection-test.c<br>
+++ b/tests/connection-test.c<br>
@@ -235,6 +235,27 @@ expected_fail_marshal(int expected_error, const char *format, ...)<br>
        assert(errno == expected_error);<br>
 }<br>
<br>
+static void<br>
+expected_fail_marshal_send(struct marshal_data *data, int expected_error,<br>
+                          const char *format, ...)<br>
+{<br>
+       struct wl_closure *closure;<br>
+       static const uint32_t opcode = 4444;<br>
+       static struct wl_object sender = { NULL, NULL, 1234 };<br>
+       struct wl_message message = { "test", format, NULL };<br>
+       va_list ap;<br>
+<br>
+       va_start(ap, format);<br>
+       closure = wl_closure_vmarshal(&sender, opcode, ap, &message);<br>
+       va_end(ap);<br>
+<br>
+       assert(closure);<br>
+       assert(wl_closure_send(closure, data->write_connection) < 0);<br>
+       assert(errno == expected_error);<br>
+<br>
+       wl_closure_destroy(closure);<br>
+}<br>
+<br>
 TEST(connection_marshal_nullables)<br>
 {<br>
        struct marshal_data data;<br>
@@ -490,6 +511,22 @@ TEST(connection_marshal_alot)<br>
        release_marshal_data(&data);<br>
 }<br>
<br>
+TEST(connection_marshal_too_big)<br>
+{<br>
+       struct marshal_data data;<br>
+       char *big_string = malloc(5000);<br>
+<br>
+       memset(big_string, ' ', 4999);<br>
+       big_string[4999] = '\0';<br>
+<br>
+       setup_marshal_data(&data);<br>
+<br>
+       expected_fail_marshal_send(&data, E2BIG, "s", big_string);<br>
+<br>
+       release_marshal_data(&data);<br>
+       free(big_string);<br>
+}<br>
+<br>
 static void<br>
 marshal_helper(const char *format, void *handler, ...)<br>
 {<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.8.3.2<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>
</font></span></blockquote></div><br><br clear="all"><br>-- <br>  Jasper<br>
</div></div>