[RFC wayland 05/12] connection: fix buffer-overflow in close_fds()

David Herrmann dh.herrmann at googlemail.com
Thu Oct 11 14:37:46 PDT 2012


If we push two messages via wl_connection_write() and both messages
contain more than MAX_FDS_OUT file-descriptors combined, then
wl_connection_flush() will write only MAX_FDS_OUT of them, but close all
pending ones, too.

Furthermore, close_fds() will copy more FDs out of the buffer than it can
hold and cause a buffer overflow. Therefore, we simply pass a maximum
limit to close_fds().

During shutdown, we simply close all available FDs.

Signed-off-by: David Herrmann <dh.herrmann at googlemail.com>
---
 src/connection.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/src/connection.c b/src/connection.c
index 1ab95d8..355fd54 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -168,9 +168,9 @@ wl_connection_create(int fd)
 }
 
 static void
-close_fds(struct wl_buffer *buffer)
+close_fds(struct wl_buffer *buffer, int max)
 {
-	int fds[MAX_FDS_OUT], i, count;
+	int32_t fds[sizeof(buffer->data) / sizeof(int32_t)], i, count;
 	size_t size;
 
 	size = buffer->head - buffer->tail;
@@ -179,6 +179,8 @@ close_fds(struct wl_buffer *buffer)
 
 	wl_buffer_copy(buffer, fds, size);
 	count = size / sizeof fds[0];
+	if (max > 0 && max < count)
+		count = max;
 	for (i = 0; i < count; i++)
 		close(fds[i]);
 	buffer->tail += size;
@@ -187,7 +189,7 @@ close_fds(struct wl_buffer *buffer)
 void
 wl_connection_destroy(struct wl_connection *connection)
 {
-	close_fds(&connection->fds_out);
+	close_fds(&connection->fds_out, -1);
 	close(connection->fd);
 	free(connection);
 }
@@ -273,7 +275,7 @@ wl_connection_flush(struct wl_connection *connection)
 		if (len == -1)
 			return -1;
 
-		close_fds(&connection->fds_out);
+		close_fds(&connection->fds_out, MAX_FDS_OUT);
 
 		connection->out.tail += len;
 	}
-- 
1.7.12.2



More information about the wayland-devel mailing list