• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2008 Kristian Høgsberg
3  * Copyright © 2013 Jason Ekstrand
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the
14  * next paragraph) shall be included in all copies or substantial
15  * portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24  * SOFTWARE.
25  */
26 
27 #define _GNU_SOURCE
28 
29 #include <math.h>
30 #include <stdlib.h>
31 #include <stdint.h>
32 #include <string.h>
33 #include <stdio.h>
34 #include <errno.h>
35 #include <sys/uio.h>
36 #include <fcntl.h>
37 #include <unistd.h>
38 #include <sys/types.h>
39 #include <sys/socket.h>
40 #include <time.h>
41 #include <ffi.h>
42 
43 #include "wayland-util.h"
44 #include "wayland-private.h"
45 #include "wayland-os.h"
46 
47 #define DIV_ROUNDUP(n, a) ( ((n) + ((a) - 1)) / (a) )
48 
49 struct wl_buffer {
50 	char data[4096];
51 	uint32_t head, tail;
52 };
53 
54 #define MASK(i) ((i) & 4095)
55 
56 #define MAX_FDS_OUT	28
57 #define CLEN		(CMSG_LEN(MAX_FDS_OUT * sizeof(int32_t)))
58 
59 struct wl_connection {
60 	struct wl_buffer in, out;
61 	struct wl_buffer fds_in, fds_out;
62 	int fd;
63 	int want_flush;
64 };
65 
66 static int
wl_buffer_put(struct wl_buffer * b,const void * data,size_t count)67 wl_buffer_put(struct wl_buffer *b, const void *data, size_t count)
68 {
69 	uint32_t head, size;
70 
71 	if (count > sizeof(b->data)) {
72 		wl_log("Data too big for buffer (%d > %d).\n",
73 		       count, sizeof(b->data));
74 		errno = E2BIG;
75 		return -1;
76 	}
77 
78 	head = MASK(b->head);
79 	if (head + count <= sizeof b->data) {
80 		memcpy(b->data + head, data, count);
81 	} else {
82 		size = sizeof b->data - head;
83 		memcpy(b->data + head, data, size);
84 		memcpy(b->data, (const char *) data + size, count - size);
85 	}
86 
87 	b->head += count;
88 
89 	return 0;
90 }
91 
92 static void
wl_buffer_put_iov(struct wl_buffer * b,struct iovec * iov,int * count)93 wl_buffer_put_iov(struct wl_buffer *b, struct iovec *iov, int *count)
94 {
95 	uint32_t head, tail;
96 
97 	head = MASK(b->head);
98 	tail = MASK(b->tail);
99 	if (head < tail) {
100 		iov[0].iov_base = b->data + head;
101 		iov[0].iov_len = tail - head;
102 		*count = 1;
103 	} else if (tail == 0) {
104 		iov[0].iov_base = b->data + head;
105 		iov[0].iov_len = sizeof b->data - head;
106 		*count = 1;
107 	} else {
108 		iov[0].iov_base = b->data + head;
109 		iov[0].iov_len = sizeof b->data - head;
110 		iov[1].iov_base = b->data;
111 		iov[1].iov_len = tail;
112 		*count = 2;
113 	}
114 }
115 
116 static void
wl_buffer_get_iov(struct wl_buffer * b,struct iovec * iov,int * count)117 wl_buffer_get_iov(struct wl_buffer *b, struct iovec *iov, int *count)
118 {
119 	uint32_t head, tail;
120 
121 	head = MASK(b->head);
122 	tail = MASK(b->tail);
123 	if (tail < head) {
124 		iov[0].iov_base = b->data + tail;
125 		iov[0].iov_len = head - tail;
126 		*count = 1;
127 	} else if (head == 0) {
128 		iov[0].iov_base = b->data + tail;
129 		iov[0].iov_len = sizeof b->data - tail;
130 		*count = 1;
131 	} else {
132 		iov[0].iov_base = b->data + tail;
133 		iov[0].iov_len = sizeof b->data - tail;
134 		iov[1].iov_base = b->data;
135 		iov[1].iov_len = head;
136 		*count = 2;
137 	}
138 }
139 
140 static void
wl_buffer_copy(struct wl_buffer * b,void * data,size_t count)141 wl_buffer_copy(struct wl_buffer *b, void *data, size_t count)
142 {
143 	uint32_t tail, size;
144 
145 	tail = MASK(b->tail);
146 	if (tail + count <= sizeof b->data) {
147 		memcpy(data, b->data + tail, count);
148 	} else {
149 		size = sizeof b->data - tail;
150 		memcpy(data, b->data + tail, size);
151 		memcpy((char *) data + size, b->data, count - size);
152 	}
153 }
154 
155 static uint32_t
wl_buffer_size(struct wl_buffer * b)156 wl_buffer_size(struct wl_buffer *b)
157 {
158 	return b->head - b->tail;
159 }
160 
161 struct wl_connection *
wl_connection_create(int fd)162 wl_connection_create(int fd)
163 {
164 	struct wl_connection *connection;
165 
166 	connection = zalloc(sizeof *connection);
167 	if (connection == NULL)
168 		return NULL;
169 
170 	connection->fd = fd;
171 
172 	return connection;
173 }
174 
175 static void
close_fds(struct wl_buffer * buffer,int max)176 close_fds(struct wl_buffer *buffer, int max)
177 {
178 	int32_t fds[sizeof(buffer->data) / sizeof(int32_t)], i, count;
179 	size_t size;
180 
181 	size = buffer->head - buffer->tail;
182 	if (size == 0)
183 		return;
184 
185 	wl_buffer_copy(buffer, fds, size);
186 	count = size / sizeof fds[0];
187 	if (max > 0 && max < count)
188 		count = max;
189 	for (i = 0; i < count; i++)
190 		close(fds[i]);
191 	buffer->tail += size;
192 }
193 
194 int
wl_connection_destroy(struct wl_connection * connection)195 wl_connection_destroy(struct wl_connection *connection)
196 {
197 	int fd = connection->fd;
198 
199 	close_fds(&connection->fds_out, -1);
200 	close_fds(&connection->fds_in, -1);
201 	free(connection);
202 
203 	return fd;
204 }
205 
206 void
wl_connection_copy(struct wl_connection * connection,void * data,size_t size)207 wl_connection_copy(struct wl_connection *connection, void *data, size_t size)
208 {
209 	wl_buffer_copy(&connection->in, data, size);
210 }
211 
212 void
wl_connection_consume(struct wl_connection * connection,size_t size)213 wl_connection_consume(struct wl_connection *connection, size_t size)
214 {
215 	connection->in.tail += size;
216 }
217 
218 static void
build_cmsg(struct wl_buffer * buffer,char * data,int * clen)219 build_cmsg(struct wl_buffer *buffer, char *data, int *clen)
220 {
221 	struct cmsghdr *cmsg;
222 	size_t size;
223 
224 	size = buffer->head - buffer->tail;
225 	if (size > MAX_FDS_OUT * sizeof(int32_t))
226 		size = MAX_FDS_OUT * sizeof(int32_t);
227 
228 	if (size > 0) {
229 		cmsg = (struct cmsghdr *) data;
230 		cmsg->cmsg_level = SOL_SOCKET;
231 		cmsg->cmsg_type = SCM_RIGHTS;
232 		cmsg->cmsg_len = CMSG_LEN(size);
233 		wl_buffer_copy(buffer, CMSG_DATA(cmsg), size);
234 		*clen = cmsg->cmsg_len;
235 	} else {
236 		*clen = 0;
237 	}
238 }
239 
240 static int
decode_cmsg(struct wl_buffer * buffer,struct msghdr * msg)241 decode_cmsg(struct wl_buffer *buffer, struct msghdr *msg)
242 {
243 	struct cmsghdr *cmsg;
244 	size_t size, max, i;
245 	int overflow = 0;
246 
247 	for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL;
248 	     cmsg = CMSG_NXTHDR(msg, cmsg)) {
249 		if (cmsg->cmsg_level != SOL_SOCKET ||
250 		    cmsg->cmsg_type != SCM_RIGHTS)
251 			continue;
252 
253 		size = cmsg->cmsg_len - CMSG_LEN(0);
254 		max = sizeof(buffer->data) - wl_buffer_size(buffer);
255 		if (size > max || overflow) {
256 			overflow = 1;
257 			size /= sizeof(int32_t);
258 			for (i = 0; i < size; i++)
259 				close(((int*)CMSG_DATA(cmsg))[i]);
260 		} else if (wl_buffer_put(buffer, CMSG_DATA(cmsg), size) < 0) {
261 				return -1;
262 		}
263 	}
264 
265 	if (overflow) {
266 		errno = EOVERFLOW;
267 		return -1;
268 	}
269 
270 	return 0;
271 }
272 
273 int
wl_connection_flush(struct wl_connection * connection)274 wl_connection_flush(struct wl_connection *connection)
275 {
276 	struct iovec iov[2];
277 	struct msghdr msg;
278 	char cmsg[CLEN];
279 	int len = 0, count, clen;
280 	uint32_t tail;
281 
282 	if (!connection->want_flush)
283 		return 0;
284 
285 	tail = connection->out.tail;
286 	while (connection->out.head - connection->out.tail > 0) {
287 		wl_buffer_get_iov(&connection->out, iov, &count);
288 
289 		build_cmsg(&connection->fds_out, cmsg, &clen);
290 
291 		msg.msg_name = NULL;
292 		msg.msg_namelen = 0;
293 		msg.msg_iov = iov;
294 		msg.msg_iovlen = count;
295 		msg.msg_control = (clen > 0) ? cmsg : NULL;
296 		msg.msg_controllen = clen;
297 		msg.msg_flags = 0;
298 
299 		do {
300 			len = sendmsg(connection->fd, &msg,
301 				      MSG_NOSIGNAL | MSG_DONTWAIT);
302 		} while (len == -1 && errno == EINTR);
303 
304 		if (len == -1)
305 			return -1;
306 
307 		close_fds(&connection->fds_out, MAX_FDS_OUT);
308 
309 		connection->out.tail += len;
310 	}
311 
312 	connection->want_flush = 0;
313 
314 	return connection->out.head - tail;
315 }
316 
317 uint32_t
wl_connection_pending_input(struct wl_connection * connection)318 wl_connection_pending_input(struct wl_connection *connection)
319 {
320 	return wl_buffer_size(&connection->in);
321 }
322 
323 int
wl_connection_read(struct wl_connection * connection)324 wl_connection_read(struct wl_connection *connection)
325 {
326 	struct iovec iov[2];
327 	struct msghdr msg;
328 	char cmsg[CLEN];
329 	int len, count, ret;
330 
331 	if (wl_buffer_size(&connection->in) >= sizeof(connection->in.data)) {
332 		errno = EOVERFLOW;
333 		return -1;
334 	}
335 
336 	wl_buffer_put_iov(&connection->in, iov, &count);
337 
338 	msg.msg_name = NULL;
339 	msg.msg_namelen = 0;
340 	msg.msg_iov = iov;
341 	msg.msg_iovlen = count;
342 	msg.msg_control = cmsg;
343 	msg.msg_controllen = sizeof cmsg;
344 	msg.msg_flags = 0;
345 
346 	do {
347 		len = wl_os_recvmsg_cloexec(connection->fd, &msg, MSG_DONTWAIT);
348 	} while (len < 0 && errno == EINTR);
349 
350 	if (len <= 0)
351 		return len;
352 
353 	ret = decode_cmsg(&connection->fds_in, &msg);
354 	if (ret)
355 		return -1;
356 
357 	connection->in.head += len;
358 
359 	return wl_connection_pending_input(connection);
360 }
361 
362 int
wl_connection_write(struct wl_connection * connection,const void * data,size_t count)363 wl_connection_write(struct wl_connection *connection,
364 		    const void *data, size_t count)
365 {
366 	if (connection->out.head - connection->out.tail +
367 	    count > ARRAY_LENGTH(connection->out.data)) {
368 		connection->want_flush = 1;
369 		if (wl_connection_flush(connection) < 0)
370 			return -1;
371 	}
372 
373 	if (wl_buffer_put(&connection->out, data, count) < 0)
374 		return -1;
375 
376 	connection->want_flush = 1;
377 
378 	return 0;
379 }
380 
381 int
wl_connection_queue(struct wl_connection * connection,const void * data,size_t count)382 wl_connection_queue(struct wl_connection *connection,
383 		    const void *data, size_t count)
384 {
385 	if (connection->out.head - connection->out.tail +
386 	    count > ARRAY_LENGTH(connection->out.data)) {
387 		connection->want_flush = 1;
388 		if (wl_connection_flush(connection) < 0)
389 			return -1;
390 	}
391 
392 	return wl_buffer_put(&connection->out, data, count);
393 }
394 
395 int
wl_message_count_arrays(const struct wl_message * message)396 wl_message_count_arrays(const struct wl_message *message)
397 {
398 	int i, arrays;
399 
400 	for (i = 0, arrays = 0; message->signature[i]; i++) {
401 		if (message->signature[i] == 'a')
402 			arrays++;
403 	}
404 
405 	return arrays;
406 }
407 
408 int
wl_connection_get_fd(struct wl_connection * connection)409 wl_connection_get_fd(struct wl_connection *connection)
410 {
411 	return connection->fd;
412 }
413 
414 static int
wl_connection_put_fd(struct wl_connection * connection,int32_t fd)415 wl_connection_put_fd(struct wl_connection *connection, int32_t fd)
416 {
417 	if (wl_buffer_size(&connection->fds_out) == MAX_FDS_OUT * sizeof fd) {
418 		connection->want_flush = 1;
419 		if (wl_connection_flush(connection) < 0)
420 			return -1;
421 	}
422 
423 	return wl_buffer_put(&connection->fds_out, &fd, sizeof fd);
424 }
425 
426 const char *
get_next_argument(const char * signature,struct argument_details * details)427 get_next_argument(const char *signature, struct argument_details *details)
428 {
429 	details->nullable = 0;
430 	for(; *signature; ++signature) {
431 		switch(*signature) {
432 		case 'i':
433 		case 'u':
434 		case 'f':
435 		case 's':
436 		case 'o':
437 		case 'n':
438 		case 'a':
439 		case 'h':
440 			details->type = *signature;
441 			return signature + 1;
442 		case '?':
443 			details->nullable = 1;
444 		}
445 	}
446 	details->type = '\0';
447 	return signature;
448 }
449 
450 int
arg_count_for_signature(const char * signature)451 arg_count_for_signature(const char *signature)
452 {
453 	int count = 0;
454 	for(; *signature; ++signature) {
455 		switch(*signature) {
456 		case 'i':
457 		case 'u':
458 		case 'f':
459 		case 's':
460 		case 'o':
461 		case 'n':
462 		case 'a':
463 		case 'h':
464 			++count;
465 		}
466 	}
467 	return count;
468 }
469 
470 int
wl_message_get_since(const struct wl_message * message)471 wl_message_get_since(const struct wl_message *message)
472 {
473 	int since;
474 
475 	since = atoi(message->signature);
476 
477 	if (since == 0)
478 		since = 1;
479 
480 	return since;
481 }
482 
483 void
wl_argument_from_va_list(const char * signature,union wl_argument * args,int count,va_list ap)484 wl_argument_from_va_list(const char *signature, union wl_argument *args,
485 			 int count, va_list ap)
486 {
487 	int i;
488 	const char *sig_iter;
489 	struct argument_details arg;
490 
491 	sig_iter = signature;
492 	for (i = 0; i < count; i++) {
493 		sig_iter = get_next_argument(sig_iter, &arg);
494 
495 		switch(arg.type) {
496 		case 'i':
497 			args[i].i = va_arg(ap, int32_t);
498 			break;
499 		case 'u':
500 			args[i].u = va_arg(ap, uint32_t);
501 			break;
502 		case 'f':
503 			args[i].f = va_arg(ap, wl_fixed_t);
504 			break;
505 		case 's':
506 			args[i].s = va_arg(ap, const char *);
507 			break;
508 		case 'o':
509 			args[i].o = va_arg(ap, struct wl_object *);
510 			break;
511 		case 'n':
512 			args[i].o = va_arg(ap, struct wl_object *);
513 			break;
514 		case 'a':
515 			args[i].a = va_arg(ap, struct wl_array *);
516 			break;
517 		case 'h':
518 			args[i].h = va_arg(ap, int32_t);
519 			break;
520 		case '\0':
521 			return;
522 		}
523 	}
524 }
525 
526 struct wl_closure *
wl_closure_marshal(struct wl_object * sender,uint32_t opcode,union wl_argument * args,const struct wl_message * message)527 wl_closure_marshal(struct wl_object *sender, uint32_t opcode,
528 		   union wl_argument *args,
529 		   const struct wl_message *message)
530 {
531 	struct wl_closure *closure;
532 	struct wl_object *object;
533 	int i, count, fd, dup_fd;
534 	const char *signature;
535 	struct argument_details arg;
536 
537 	count = arg_count_for_signature(message->signature);
538 	if (count > WL_CLOSURE_MAX_ARGS) {
539 		wl_log("too many args (%d)\n", count);
540 		errno = EINVAL;
541 		return NULL;
542 	}
543 
544 	closure = malloc(sizeof *closure);
545 	if (closure == NULL) {
546 		errno = ENOMEM;
547 		return NULL;
548 	}
549 
550 	memcpy(closure->args, args, count * sizeof *args);
551 
552 	signature = message->signature;
553 	for (i = 0; i < count; i++) {
554 		signature = get_next_argument(signature, &arg);
555 
556 		switch (arg.type) {
557 		case 'f':
558 		case 'u':
559 		case 'i':
560 			break;
561 		case 's':
562 			if (!arg.nullable && args[i].s == NULL)
563 				goto err_null;
564 			break;
565 		case 'o':
566 			if (!arg.nullable && args[i].o == NULL)
567 				goto err_null;
568 			break;
569 		case 'n':
570 			object = args[i].o;
571 			if (!arg.nullable && object == NULL)
572 				goto err_null;
573 
574 			closure->args[i].n = object ? object->id : 0;
575 			break;
576 		case 'a':
577 			if (!arg.nullable && args[i].a == NULL)
578 				goto err_null;
579 			break;
580 		case 'h':
581 			fd = args[i].h;
582 			dup_fd = wl_os_dupfd_cloexec(fd, 0);
583 			if (dup_fd < 0)
584 				wl_abort("dup failed: %s\n", strerror(errno));
585 			closure->args[i].h = dup_fd;
586 			break;
587 		default:
588 			wl_abort("unhandled format code: '%c'\n", arg.type);
589 			break;
590 		}
591 	}
592 
593 	closure->sender_id = sender->id;
594 	closure->opcode = opcode;
595 	closure->message = message;
596 	closure->count = count;
597 
598 	return closure;
599 
600 err_null:
601 	wl_closure_destroy(closure);
602 	wl_log("error marshalling arguments for %s (signature %s): "
603 	       "null value passed for arg %i\n", message->name,
604 	       message->signature, i);
605 	errno = EINVAL;
606 	return NULL;
607 }
608 
609 struct wl_closure *
wl_closure_vmarshal(struct wl_object * sender,uint32_t opcode,va_list ap,const struct wl_message * message)610 wl_closure_vmarshal(struct wl_object *sender, uint32_t opcode, va_list ap,
611 		    const struct wl_message *message)
612 {
613 	union wl_argument args[WL_CLOSURE_MAX_ARGS];
614 
615 	wl_argument_from_va_list(message->signature, args,
616 				 WL_CLOSURE_MAX_ARGS, ap);
617 
618 	return wl_closure_marshal(sender, opcode, args, message);
619 }
620 
621 struct wl_closure *
wl_connection_demarshal(struct wl_connection * connection,uint32_t size,struct wl_map * objects,const struct wl_message * message)622 wl_connection_demarshal(struct wl_connection *connection,
623 			uint32_t size,
624 			struct wl_map *objects,
625 			const struct wl_message *message)
626 {
627 	uint32_t *p, *next, *end, length, id;
628 	int fd;
629 	char *s;
630 	unsigned int i, count, num_arrays;
631 	const char *signature;
632 	struct argument_details arg;
633 	struct wl_closure *closure;
634 	struct wl_array *array, *array_extra;
635 
636 	count = arg_count_for_signature(message->signature);
637 	if (count > WL_CLOSURE_MAX_ARGS) {
638 		wl_log("too many args (%d)\n", count);
639 		errno = EINVAL;
640 		wl_connection_consume(connection, size);
641 		return NULL;
642 	}
643 
644 	num_arrays = wl_message_count_arrays(message);
645 	closure = malloc(sizeof *closure + size + num_arrays * sizeof *array);
646 	if (closure == NULL) {
647 		errno = ENOMEM;
648 		wl_connection_consume(connection, size);
649 		return NULL;
650 	}
651 
652 	array_extra = closure->extra;
653 	p = (uint32_t *)(closure->extra + num_arrays);
654 	end = p + size / sizeof *p;
655 
656 	wl_connection_copy(connection, p, size);
657 	closure->sender_id = *p++;
658 	closure->opcode = *p++ & 0x0000ffff;
659 
660 	signature = message->signature;
661 	for (i = 0; i < count; i++) {
662 		signature = get_next_argument(signature, &arg);
663 
664 		if (arg.type != 'h' && p + 1 > end) {
665 			wl_log("message too short, "
666 			       "object (%d), message %s(%s)\n",
667 			       *p, message->name, message->signature);
668 			errno = EINVAL;
669 			goto err;
670 		}
671 
672 		switch (arg.type) {
673 		case 'u':
674 			closure->args[i].u = *p++;
675 			break;
676 		case 'i':
677 			closure->args[i].i = *p++;
678 			break;
679 		case 'f':
680 			closure->args[i].f = *p++;
681 			break;
682 		case 's':
683 			length = *p++;
684 
685 			if (length == 0) {
686 				closure->args[i].s = NULL;
687 				break;
688 			}
689 
690 			next = p + DIV_ROUNDUP(length, sizeof *p);
691 			if (next > end) {
692 				wl_log("message too short, "
693 				       "object (%d), message %s(%s)\n",
694 				       closure->sender_id, message->name,
695 				       message->signature);
696 				errno = EINVAL;
697 				goto err;
698 			}
699 
700 			s = (char *) p;
701 
702 			if (length > 0 && s[length - 1] != '\0') {
703 				wl_log("string not nul-terminated, "
704 				       "message %s(%s)\n",
705 				       message->name, message->signature);
706 				errno = EINVAL;
707 				goto err;
708 			}
709 
710 			closure->args[i].s = s;
711 			p = next;
712 			break;
713 		case 'o':
714 			id = *p++;
715 			closure->args[i].n = id;
716 
717 			if (id == 0 && !arg.nullable) {
718 				wl_log("NULL object received on non-nullable "
719 				       "type, message %s(%s)\n", message->name,
720 				       message->signature);
721 				errno = EINVAL;
722 				goto err;
723 			}
724 			break;
725 		case 'n':
726 			id = *p++;
727 			closure->args[i].n = id;
728 
729 			if (id == 0 && !arg.nullable) {
730 				wl_log("NULL new ID received on non-nullable "
731 				       "type, message %s(%s)\n", message->name,
732 				       message->signature);
733 				errno = EINVAL;
734 				goto err;
735 			}
736 
737 			if (wl_map_reserve_new(objects, id) < 0) {
738 				wl_log("not a valid new object id (%u), "
739 				       "message %s(%s)\n",
740 				       id, message->name, message->signature);
741 				errno = EINVAL;
742 				goto err;
743 			}
744 
745 			break;
746 		case 'a':
747 			length = *p++;
748 
749 			next = p + DIV_ROUNDUP(length, sizeof *p);
750 			if (next > end) {
751 				wl_log("message too short, "
752 				       "object (%d), message %s(%s)\n",
753 				       closure->sender_id, message->name,
754 				       message->signature);
755 				errno = EINVAL;
756 				goto err;
757 			}
758 
759 			array_extra->size = length;
760 			array_extra->alloc = 0;
761 			array_extra->data = p;
762 
763 			closure->args[i].a = array_extra++;
764 			p = next;
765 			break;
766 		case 'h':
767 			if (connection->fds_in.tail == connection->fds_in.head) {
768 				wl_log("file descriptor expected, "
769 				       "object (%d), message %s(%s)\n",
770 				       closure->sender_id, message->name,
771 				       message->signature);
772 				errno = EINVAL;
773 				goto err;
774 			}
775 
776 			wl_buffer_copy(&connection->fds_in, &fd, sizeof fd);
777 			connection->fds_in.tail += sizeof fd;
778 			closure->args[i].h = fd;
779 			break;
780 		default:
781 			wl_abort("unknown type\n");
782 			break;
783 		}
784 	}
785 
786 	closure->count = count;
787 	closure->message = message;
788 
789 	wl_connection_consume(connection, size);
790 
791 	return closure;
792 
793  err:
794 	wl_closure_destroy(closure);
795 	wl_connection_consume(connection, size);
796 
797 	return NULL;
798 }
799 
800 int
wl_closure_lookup_objects(struct wl_closure * closure,struct wl_map * objects)801 wl_closure_lookup_objects(struct wl_closure *closure, struct wl_map *objects)
802 {
803 	struct wl_object *object;
804 	const struct wl_message *message;
805 	const char *signature;
806 	struct argument_details arg;
807 	int i, count;
808 	uint32_t id;
809 
810 	message = closure->message;
811 	signature = message->signature;
812 	count = arg_count_for_signature(signature);
813 	for (i = 0; i < count; i++) {
814 		signature = get_next_argument(signature, &arg);
815 		switch (arg.type) {
816 		case 'o':
817 			id = closure->args[i].n;
818 			closure->args[i].o = NULL;
819 
820 			object = wl_map_lookup(objects, id);
821 			if (object == WL_ZOMBIE_OBJECT) {
822 				/* references object we've already
823 				 * destroyed client side */
824 				object = NULL;
825 			} else if (object == NULL && id != 0) {
826 				wl_log("unknown object (%u), message %s(%s)\n",
827 				       id, message->name, message->signature);
828 				errno = EINVAL;
829 				return -1;
830 			}
831 
832 			if (object != NULL && message->types[i] != NULL &&
833 			    !wl_interface_equal((object)->interface,
834 						message->types[i])) {
835 				wl_log("invalid object (%u), type (%s), "
836 				       "message %s(%s)\n",
837 				       id, (object)->interface->name,
838 				       message->name, message->signature);
839 				errno = EINVAL;
840 				return -1;
841 			}
842 			closure->args[i].o = object;
843 		}
844 	}
845 
846 	return 0;
847 }
848 
849 static void
convert_arguments_to_ffi(const char * signature,uint32_t flags,union wl_argument * args,int count,ffi_type ** ffi_types,void ** ffi_args)850 convert_arguments_to_ffi(const char *signature, uint32_t flags,
851 			 union wl_argument *args,
852 			 int count, ffi_type **ffi_types, void** ffi_args)
853 {
854 	int i;
855 	const char *sig_iter;
856 	struct argument_details arg;
857 
858 	sig_iter = signature;
859 	for (i = 0; i < count; i++) {
860 		sig_iter = get_next_argument(sig_iter, &arg);
861 
862 		switch(arg.type) {
863 		case 'i':
864 			ffi_types[i] = &ffi_type_sint32;
865 			ffi_args[i] = &args[i].i;
866 			break;
867 		case 'u':
868 			ffi_types[i] = &ffi_type_uint32;
869 			ffi_args[i] = &args[i].u;
870 			break;
871 		case 'f':
872 			ffi_types[i] = &ffi_type_sint32;
873 			ffi_args[i] = &args[i].f;
874 			break;
875 		case 's':
876 			ffi_types[i] = &ffi_type_pointer;
877 			ffi_args[i] = &args[i].s;
878 			break;
879 		case 'o':
880 			ffi_types[i] = &ffi_type_pointer;
881 			ffi_args[i] = &args[i].o;
882 			break;
883 		case 'n':
884 			if (flags & WL_CLOSURE_INVOKE_CLIENT) {
885 				ffi_types[i] = &ffi_type_pointer;
886 				ffi_args[i] = &args[i].o;
887 			} else {
888 				ffi_types[i] = &ffi_type_uint32;
889 				ffi_args[i] = &args[i].n;
890 			}
891 			break;
892 		case 'a':
893 			ffi_types[i] = &ffi_type_pointer;
894 			ffi_args[i] = &args[i].a;
895 			break;
896 		case 'h':
897 			ffi_types[i] = &ffi_type_sint32;
898 			ffi_args[i] = &args[i].h;
899 			break;
900 		default:
901 			wl_abort("unknown type\n");
902 			break;
903 		}
904 	}
905 }
906 
907 void
wl_closure_invoke(struct wl_closure * closure,uint32_t flags,struct wl_object * target,uint32_t opcode,void * data)908 wl_closure_invoke(struct wl_closure *closure, uint32_t flags,
909 		  struct wl_object *target, uint32_t opcode, void *data)
910 {
911 	int count;
912 	ffi_cif cif;
913 	ffi_type *ffi_types[WL_CLOSURE_MAX_ARGS + 2];
914 	void * ffi_args[WL_CLOSURE_MAX_ARGS + 2];
915 	void (* const *implementation)(void);
916 
917 	count = arg_count_for_signature(closure->message->signature);
918 
919 	ffi_types[0] = &ffi_type_pointer;
920 	ffi_args[0] = &data;
921 	ffi_types[1] = &ffi_type_pointer;
922 	ffi_args[1] = &target;
923 
924 	convert_arguments_to_ffi(closure->message->signature, flags, closure->args,
925 				 count, ffi_types + 2, ffi_args + 2);
926 
927 	ffi_prep_cif(&cif, FFI_DEFAULT_ABI,
928 		     count + 2, &ffi_type_void, ffi_types);
929 
930 	implementation = target->implementation;
931 	if (!implementation[opcode]) {
932 		wl_abort("listener function for opcode %u of %s is NULL\n",
933 			 opcode, target->interface->name);
934 	}
935 	ffi_call(&cif, implementation[opcode], NULL, ffi_args);
936 }
937 
938 void
wl_closure_dispatch(struct wl_closure * closure,wl_dispatcher_func_t dispatcher,struct wl_object * target,uint32_t opcode)939 wl_closure_dispatch(struct wl_closure *closure, wl_dispatcher_func_t dispatcher,
940 		    struct wl_object *target, uint32_t opcode)
941 {
942 	dispatcher(target->implementation, target, opcode, closure->message,
943 		   closure->args);
944 }
945 
946 static int
copy_fds_to_connection(struct wl_closure * closure,struct wl_connection * connection)947 copy_fds_to_connection(struct wl_closure *closure,
948 		       struct wl_connection *connection)
949 {
950 	const struct wl_message *message = closure->message;
951 	uint32_t i, count;
952 	struct argument_details arg;
953 	const char *signature = message->signature;
954 	int fd;
955 
956 	count = arg_count_for_signature(signature);
957 	for (i = 0; i < count; i++) {
958 		signature = get_next_argument(signature, &arg);
959 		if (arg.type != 'h')
960 			continue;
961 
962 		fd = closure->args[i].h;
963 		if (wl_connection_put_fd(connection, fd)) {
964 			wl_log("request could not be marshaled: "
965 			       "can't send file descriptor");
966 			return -1;
967 		}
968 	}
969 
970 	return 0;
971 }
972 
973 
974 static uint32_t
buffer_size_for_closure(struct wl_closure * closure)975 buffer_size_for_closure(struct wl_closure *closure)
976 {
977 	const struct wl_message *message = closure->message;
978 	int i, count;
979 	struct argument_details arg;
980 	const char *signature;
981 	uint32_t size, buffer_size = 0;
982 
983 	signature = message->signature;
984 	count = arg_count_for_signature(signature);
985 	for (i = 0; i < count; i++) {
986 		signature = get_next_argument(signature, &arg);
987 
988 		switch (arg.type) {
989 		case 'h':
990 			break;
991 		case 'u':
992 		case 'i':
993 		case 'f':
994 		case 'o':
995 		case 'n':
996 			buffer_size++;
997 			break;
998 		case 's':
999 			if (closure->args[i].s == NULL) {
1000 				buffer_size++;
1001 				break;
1002 			}
1003 
1004 			size = strlen(closure->args[i].s) + 1;
1005 			buffer_size += 1 + DIV_ROUNDUP(size, sizeof(uint32_t));
1006 			break;
1007 		case 'a':
1008 			if (closure->args[i].a == NULL) {
1009 				buffer_size++;
1010 				break;
1011 			}
1012 
1013 			size = closure->args[i].a->size;
1014 			buffer_size += (1 + DIV_ROUNDUP(size, sizeof(uint32_t)));
1015 			break;
1016 		default:
1017 			break;
1018 		}
1019 	}
1020 
1021 	return buffer_size + 2;
1022 }
1023 
1024 static int
serialize_closure(struct wl_closure * closure,uint32_t * buffer,size_t buffer_count)1025 serialize_closure(struct wl_closure *closure, uint32_t *buffer,
1026 		  size_t buffer_count)
1027 {
1028 	const struct wl_message *message = closure->message;
1029 	unsigned int i, count, size;
1030 	uint32_t *p, *end;
1031 	struct argument_details arg;
1032 	const char *signature;
1033 
1034 	if (buffer_count < 2)
1035 		goto overflow;
1036 
1037 	p = buffer + 2;
1038 	end = buffer + buffer_count;
1039 
1040 	signature = message->signature;
1041 	count = arg_count_for_signature(signature);
1042 	for (i = 0; i < count; i++) {
1043 		signature = get_next_argument(signature, &arg);
1044 
1045 		if (arg.type == 'h')
1046 			continue;
1047 
1048 		if (p + 1 > end)
1049 			goto overflow;
1050 
1051 		switch (arg.type) {
1052 		case 'u':
1053 			*p++ = closure->args[i].u;
1054 			break;
1055 		case 'i':
1056 			*p++ = closure->args[i].i;
1057 			break;
1058 		case 'f':
1059 			*p++ = closure->args[i].f;
1060 			break;
1061 		case 'o':
1062 			*p++ = closure->args[i].o ? closure->args[i].o->id : 0;
1063 			break;
1064 		case 'n':
1065 			*p++ = closure->args[i].n;
1066 			break;
1067 		case 's':
1068 			if (closure->args[i].s == NULL) {
1069 				*p++ = 0;
1070 				break;
1071 			}
1072 
1073 			size = strlen(closure->args[i].s) + 1;
1074 			*p++ = size;
1075 
1076 			if (p + DIV_ROUNDUP(size, sizeof *p) > end)
1077 				goto overflow;
1078 
1079 			memcpy(p, closure->args[i].s, size);
1080 			p += DIV_ROUNDUP(size, sizeof *p);
1081 			break;
1082 		case 'a':
1083 			if (closure->args[i].a == NULL) {
1084 				*p++ = 0;
1085 				break;
1086 			}
1087 
1088 			size = closure->args[i].a->size;
1089 			*p++ = size;
1090 
1091 			if (p + DIV_ROUNDUP(size, sizeof *p) > end)
1092 				goto overflow;
1093 
1094 			memcpy(p, closure->args[i].a->data, size);
1095 			p += DIV_ROUNDUP(size, sizeof *p);
1096 			break;
1097 		default:
1098 			break;
1099 		}
1100 	}
1101 
1102 	size = (p - buffer) * sizeof *p;
1103 
1104 	buffer[0] = closure->sender_id;
1105 	buffer[1] = size << 16 | (closure->opcode & 0x0000ffff);
1106 
1107 	return size;
1108 
1109 overflow:
1110 	errno = ERANGE;
1111 	return -1;
1112 }
1113 
1114 int
wl_closure_send(struct wl_closure * closure,struct wl_connection * connection)1115 wl_closure_send(struct wl_closure *closure, struct wl_connection *connection)
1116 {
1117 	int size;
1118 	uint32_t buffer_size;
1119 	uint32_t *buffer;
1120 	int result;
1121 
1122 	if (copy_fds_to_connection(closure, connection))
1123 		return -1;
1124 
1125 	buffer_size = buffer_size_for_closure(closure);
1126 	buffer = zalloc(buffer_size * sizeof buffer[0]);
1127 	if (buffer == NULL)
1128 		return -1;
1129 
1130 	size = serialize_closure(closure, buffer, buffer_size);
1131 	if (size < 0) {
1132 		free(buffer);
1133 		return -1;
1134 	}
1135 
1136 	result = wl_connection_write(connection, buffer, size);
1137 	free(buffer);
1138 
1139 	return result;
1140 }
1141 
1142 int
wl_closure_queue(struct wl_closure * closure,struct wl_connection * connection)1143 wl_closure_queue(struct wl_closure *closure, struct wl_connection *connection)
1144 {
1145 	int size;
1146 	uint32_t buffer_size;
1147 	uint32_t *buffer;
1148 	int result;
1149 
1150 	if (copy_fds_to_connection(closure, connection))
1151 		return -1;
1152 
1153 	buffer_size = buffer_size_for_closure(closure);
1154 	buffer = malloc(buffer_size * sizeof buffer[0]);
1155 	if (buffer == NULL)
1156 		return -1;
1157 
1158 	size = serialize_closure(closure, buffer, buffer_size);
1159 	if (size < 0) {
1160 		free(buffer);
1161 		return -1;
1162 	}
1163 
1164 	result = wl_connection_queue(connection, buffer, size);
1165 	free(buffer);
1166 
1167 	return result;
1168 }
1169 
1170 void
wl_closure_print(struct wl_closure * closure,struct wl_object * target,int send)1171 wl_closure_print(struct wl_closure *closure, struct wl_object *target, int send)
1172 {
1173 	int i;
1174 	struct argument_details arg;
1175 	const char *signature = closure->message->signature;
1176 	struct timespec tp;
1177 	unsigned int time;
1178 
1179 	clock_gettime(CLOCK_REALTIME, &tp);
1180 	time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
1181 
1182 	fprintf(stderr, "[%10.3f] %s%s@%u.%s(",
1183 		time / 1000.0,
1184 		send ? " -> " : "",
1185 		target->interface->name, target->id,
1186 		closure->message->name);
1187 
1188 	for (i = 0; i < closure->count; i++) {
1189 		signature = get_next_argument(signature, &arg);
1190 		if (i > 0)
1191 			fprintf(stderr, ", ");
1192 
1193 		switch (arg.type) {
1194 		case 'u':
1195 			fprintf(stderr, "%u", closure->args[i].u);
1196 			break;
1197 		case 'i':
1198 			fprintf(stderr, "%d", closure->args[i].i);
1199 			break;
1200 		case 'f':
1201 			fprintf(stderr, "%f",
1202 				wl_fixed_to_double(closure->args[i].f));
1203 			break;
1204 		case 's':
1205 			fprintf(stderr, "\"%s\"", closure->args[i].s);
1206 			break;
1207 		case 'o':
1208 			if (closure->args[i].o)
1209 				fprintf(stderr, "%s@%u",
1210 					closure->args[i].o->interface->name,
1211 					closure->args[i].o->id);
1212 			else
1213 				fprintf(stderr, "nil");
1214 			break;
1215 		case 'n':
1216 			fprintf(stderr, "new id %s@",
1217 				(closure->message->types[i]) ?
1218 				 closure->message->types[i]->name :
1219 				  "[unknown]");
1220 			if (closure->args[i].n != 0)
1221 				fprintf(stderr, "%u", closure->args[i].n);
1222 			else
1223 				fprintf(stderr, "nil");
1224 			break;
1225 		case 'a':
1226 			fprintf(stderr, "array");
1227 			break;
1228 		case 'h':
1229 			fprintf(stderr, "fd %d", closure->args[i].h);
1230 			break;
1231 		}
1232 	}
1233 
1234 	fprintf(stderr, ")\n");
1235 }
1236 
1237 void
wl_closure_destroy(struct wl_closure * closure)1238 wl_closure_destroy(struct wl_closure *closure)
1239 {
1240 	free(closure);
1241 }
1242