• 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 static inline uint32_t
div_roundup(uint32_t n,size_t a)48 div_roundup(uint32_t n, size_t a)
49 {
50 	/* The cast to uint64_t is necessary to prevent overflow when rounding
51 	 * values close to UINT32_MAX. After the division it is again safe to
52 	 * cast back to uint32_t.
53 	 */
54 	return (uint32_t) (((uint64_t) n + (a - 1)) / a);
55 }
56 
57 struct wl_buffer {
58 	char data[4096];
59 	uint32_t head, tail;
60 };
61 
62 #define MASK(i) ((i) & 4095)
63 
64 #define MAX_FDS_OUT	28
65 #define CLEN		(CMSG_LEN(MAX_FDS_OUT * sizeof(int32_t)))
66 
67 struct wl_connection {
68 	struct wl_buffer in, out;
69 	struct wl_buffer fds_in, fds_out;
70 	int fd;
71 	int want_flush;
72 };
73 
74 static int
wl_buffer_put(struct wl_buffer * b,const void * data,size_t count)75 wl_buffer_put(struct wl_buffer *b, const void *data, size_t count)
76 {
77 	uint32_t head, size;
78 
79 	if (count > sizeof(b->data)) {
80 		wl_log("Data too big for buffer (%d > %d).\n",
81 		       count, sizeof(b->data));
82 		errno = E2BIG;
83 		return -1;
84 	}
85 
86 	head = MASK(b->head);
87 	if (head + count <= sizeof b->data) {
88 		memcpy(b->data + head, data, count);
89 	} else {
90 		size = sizeof b->data - head;
91 		memcpy(b->data + head, data, size);
92 		memcpy(b->data, (const char *) data + size, count - size);
93 	}
94 
95 	b->head += count;
96 
97 	return 0;
98 }
99 
100 static void
wl_buffer_put_iov(struct wl_buffer * b,struct iovec * iov,int * count)101 wl_buffer_put_iov(struct wl_buffer *b, struct iovec *iov, int *count)
102 {
103 	uint32_t head, tail;
104 
105 	head = MASK(b->head);
106 	tail = MASK(b->tail);
107 	if (head < tail) {
108 		iov[0].iov_base = b->data + head;
109 		iov[0].iov_len = tail - head;
110 		*count = 1;
111 	} else if (tail == 0) {
112 		iov[0].iov_base = b->data + head;
113 		iov[0].iov_len = sizeof b->data - head;
114 		*count = 1;
115 	} else {
116 		iov[0].iov_base = b->data + head;
117 		iov[0].iov_len = sizeof b->data - head;
118 		iov[1].iov_base = b->data;
119 		iov[1].iov_len = tail;
120 		*count = 2;
121 	}
122 }
123 
124 static void
wl_buffer_get_iov(struct wl_buffer * b,struct iovec * iov,int * count)125 wl_buffer_get_iov(struct wl_buffer *b, struct iovec *iov, int *count)
126 {
127 	uint32_t head, tail;
128 
129 	head = MASK(b->head);
130 	tail = MASK(b->tail);
131 	if (tail < head) {
132 		iov[0].iov_base = b->data + tail;
133 		iov[0].iov_len = head - tail;
134 		*count = 1;
135 	} else if (head == 0) {
136 		iov[0].iov_base = b->data + tail;
137 		iov[0].iov_len = sizeof b->data - tail;
138 		*count = 1;
139 	} else {
140 		iov[0].iov_base = b->data + tail;
141 		iov[0].iov_len = sizeof b->data - tail;
142 		iov[1].iov_base = b->data;
143 		iov[1].iov_len = head;
144 		*count = 2;
145 	}
146 }
147 
148 static void
wl_buffer_copy(struct wl_buffer * b,void * data,size_t count)149 wl_buffer_copy(struct wl_buffer *b, void *data, size_t count)
150 {
151 	uint32_t tail, size;
152 
153 	tail = MASK(b->tail);
154 	if (tail + count <= sizeof b->data) {
155 		memcpy(data, b->data + tail, count);
156 	} else {
157 		size = sizeof b->data - tail;
158 		memcpy(data, b->data + tail, size);
159 		memcpy((char *) data + size, b->data, count - size);
160 	}
161 }
162 
163 static uint32_t
wl_buffer_size(struct wl_buffer * b)164 wl_buffer_size(struct wl_buffer *b)
165 {
166 	return b->head - b->tail;
167 }
168 
169 struct wl_connection *
wl_connection_create(int fd)170 wl_connection_create(int fd)
171 {
172 	struct wl_connection *connection;
173 
174 	connection = zalloc(sizeof *connection);
175 	if (connection == NULL)
176 		return NULL;
177 
178 	connection->fd = fd;
179 
180 	return connection;
181 }
182 
183 static void
close_fds(struct wl_buffer * buffer,int max)184 close_fds(struct wl_buffer *buffer, int max)
185 {
186 	int32_t fds[sizeof(buffer->data) / sizeof(int32_t)], i, count;
187 	size_t size;
188 
189 	size = wl_buffer_size(buffer);
190 	if (size == 0)
191 		return;
192 
193 	wl_buffer_copy(buffer, fds, size);
194 	count = size / sizeof fds[0];
195 	if (max > 0 && max < count)
196 		count = max;
197 	size = count * sizeof fds[0];
198 	for (i = 0; i < count; i++)
199 		close(fds[i]);
200 	buffer->tail += size;
201 }
202 
203 void
wl_connection_close_fds_in(struct wl_connection * connection,int max)204 wl_connection_close_fds_in(struct wl_connection *connection, int max)
205 {
206 	close_fds(&connection->fds_in, max);
207 }
208 
209 int
wl_connection_destroy(struct wl_connection * connection)210 wl_connection_destroy(struct wl_connection *connection)
211 {
212 	int fd = connection->fd;
213 
214 	close_fds(&connection->fds_out, -1);
215 	close_fds(&connection->fds_in, -1);
216 	free(connection);
217 
218 	return fd;
219 }
220 
221 void
wl_connection_copy(struct wl_connection * connection,void * data,size_t size)222 wl_connection_copy(struct wl_connection *connection, void *data, size_t size)
223 {
224 	wl_buffer_copy(&connection->in, data, size);
225 }
226 
227 void
wl_connection_consume(struct wl_connection * connection,size_t size)228 wl_connection_consume(struct wl_connection *connection, size_t size)
229 {
230 	connection->in.tail += size;
231 }
232 
233 static void
build_cmsg(struct wl_buffer * buffer,char * data,int * clen)234 build_cmsg(struct wl_buffer *buffer, char *data, int *clen)
235 {
236 	struct cmsghdr *cmsg;
237 	size_t size;
238 
239 	size = wl_buffer_size(buffer);
240 	if (size > MAX_FDS_OUT * sizeof(int32_t))
241 		size = MAX_FDS_OUT * sizeof(int32_t);
242 
243 	if (size > 0) {
244 		cmsg = (struct cmsghdr *) data;
245 		cmsg->cmsg_level = SOL_SOCKET;
246 		cmsg->cmsg_type = SCM_RIGHTS;
247 		cmsg->cmsg_len = CMSG_LEN(size);
248 		wl_buffer_copy(buffer, CMSG_DATA(cmsg), size);
249 		*clen = cmsg->cmsg_len;
250 	} else {
251 		*clen = 0;
252 	}
253 }
254 
255 static int
decode_cmsg(struct wl_buffer * buffer,struct msghdr * msg)256 decode_cmsg(struct wl_buffer *buffer, struct msghdr *msg)
257 {
258 	struct cmsghdr *cmsg;
259 	size_t size, max, i;
260 	int overflow = 0;
261 
262 	for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL;
263 	     cmsg = CMSG_NXTHDR(msg, cmsg)) {
264 		if (cmsg->cmsg_level != SOL_SOCKET ||
265 		    cmsg->cmsg_type != SCM_RIGHTS)
266 			continue;
267 
268 		size = cmsg->cmsg_len - CMSG_LEN(0);
269 		max = sizeof(buffer->data) - wl_buffer_size(buffer);
270 		if (size > max || overflow) {
271 			overflow = 1;
272 			size /= sizeof(int32_t);
273 			for (i = 0; i < size; i++)
274 				close(((int*)CMSG_DATA(cmsg))[i]);
275 		} else if (wl_buffer_put(buffer, CMSG_DATA(cmsg), size) < 0) {
276 				return -1;
277 		}
278 	}
279 
280 	if (overflow) {
281 		errno = EOVERFLOW;
282 		return -1;
283 	}
284 
285 	return 0;
286 }
287 
288 int
wl_connection_flush(struct wl_connection * connection)289 wl_connection_flush(struct wl_connection *connection)
290 {
291 	struct iovec iov[2];
292 	struct msghdr msg;
293 	char cmsg[CLEN];
294 	int len = 0, count, clen;
295 	uint32_t tail;
296 
297 	if (!connection->want_flush)
298 		return 0;
299 
300 	tail = connection->out.tail;
301 	while (connection->out.head - connection->out.tail > 0) {
302 		wl_buffer_get_iov(&connection->out, iov, &count);
303 
304 		build_cmsg(&connection->fds_out, cmsg, &clen);
305 
306 		msg.msg_name = NULL;
307 		msg.msg_namelen = 0;
308 		msg.msg_iov = iov;
309 		msg.msg_iovlen = count;
310 		msg.msg_control = (clen > 0) ? cmsg : NULL;
311 		msg.msg_controllen = clen;
312 		msg.msg_flags = 0;
313 
314 		do {
315 			len = sendmsg(connection->fd, &msg,
316 				      MSG_NOSIGNAL | MSG_DONTWAIT);
317 		} while (len == -1 && errno == EINTR);
318 
319 		if (len == -1)
320 			return -1;
321 
322 		close_fds(&connection->fds_out, MAX_FDS_OUT);
323 
324 		connection->out.tail += len;
325 	}
326 
327 	connection->want_flush = 0;
328 
329 	return connection->out.head - tail;
330 }
331 
332 uint32_t
wl_connection_pending_input(struct wl_connection * connection)333 wl_connection_pending_input(struct wl_connection *connection)
334 {
335 	return wl_buffer_size(&connection->in);
336 }
337 
338 int
wl_connection_read(struct wl_connection * connection)339 wl_connection_read(struct wl_connection *connection)
340 {
341 	struct iovec iov[2];
342 	struct msghdr msg;
343 	char cmsg[CLEN];
344 	int len, count, ret;
345 
346 	if (wl_buffer_size(&connection->in) >= sizeof(connection->in.data)) {
347 		errno = EOVERFLOW;
348 		return -1;
349 	}
350 
351 	wl_buffer_put_iov(&connection->in, iov, &count);
352 
353 	msg.msg_name = NULL;
354 	msg.msg_namelen = 0;
355 	msg.msg_iov = iov;
356 	msg.msg_iovlen = count;
357 	msg.msg_control = cmsg;
358 	msg.msg_controllen = sizeof cmsg;
359 	msg.msg_flags = 0;
360 
361 	do {
362 		len = wl_os_recvmsg_cloexec(connection->fd, &msg, MSG_DONTWAIT);
363 	} while (len < 0 && errno == EINTR);
364 
365 	if (len <= 0)
366 		return len;
367 
368 	ret = decode_cmsg(&connection->fds_in, &msg);
369 	if (ret)
370 		return -1;
371 
372 	connection->in.head += len;
373 
374 	return wl_connection_pending_input(connection);
375 }
376 
377 int
wl_connection_write(struct wl_connection * connection,const void * data,size_t count)378 wl_connection_write(struct wl_connection *connection,
379 		    const void *data, size_t count)
380 {
381 	if (connection->out.head - connection->out.tail +
382 	    count > ARRAY_LENGTH(connection->out.data)) {
383 		connection->want_flush = 1;
384 		if (wl_connection_flush(connection) < 0)
385 			return -1;
386 	}
387 
388 	if (wl_buffer_put(&connection->out, data, count) < 0)
389 		return -1;
390 
391 	connection->want_flush = 1;
392 
393 	return 0;
394 }
395 
396 int
wl_connection_queue(struct wl_connection * connection,const void * data,size_t count)397 wl_connection_queue(struct wl_connection *connection,
398 		    const void *data, size_t count)
399 {
400 	if (connection->out.head - connection->out.tail +
401 	    count > ARRAY_LENGTH(connection->out.data)) {
402 		connection->want_flush = 1;
403 		if (wl_connection_flush(connection) < 0)
404 			return -1;
405 	}
406 
407 	return wl_buffer_put(&connection->out, data, count);
408 }
409 
410 int
wl_message_count_arrays(const struct wl_message * message)411 wl_message_count_arrays(const struct wl_message *message)
412 {
413 	int i, arrays;
414 
415 	for (i = 0, arrays = 0; message->signature[i]; i++) {
416 		if (message->signature[i] == 'a')
417 			arrays++;
418 	}
419 
420 	return arrays;
421 }
422 
423 int
wl_connection_get_fd(struct wl_connection * connection)424 wl_connection_get_fd(struct wl_connection *connection)
425 {
426 	return connection->fd;
427 }
428 
429 static int
wl_connection_put_fd(struct wl_connection * connection,int32_t fd)430 wl_connection_put_fd(struct wl_connection *connection, int32_t fd)
431 {
432 	if (wl_buffer_size(&connection->fds_out) == MAX_FDS_OUT * sizeof fd) {
433 		connection->want_flush = 1;
434 		if (wl_connection_flush(connection) < 0)
435 			return -1;
436 	}
437 
438 	return wl_buffer_put(&connection->fds_out, &fd, sizeof fd);
439 }
440 
441 const char *
get_next_argument(const char * signature,struct argument_details * details)442 get_next_argument(const char *signature, struct argument_details *details)
443 {
444 	details->nullable = 0;
445 	for(; *signature; ++signature) {
446 		switch(*signature) {
447 		case 'i':
448 		case 'u':
449 		case 'f':
450 		case 's':
451 		case 'o':
452 		case 'n':
453 		case 'a':
454 		case 'h':
455 			details->type = *signature;
456 			return signature + 1;
457 		case '?':
458 			details->nullable = 1;
459 		}
460 	}
461 	details->type = '\0';
462 	return signature;
463 }
464 
465 int
arg_count_for_signature(const char * signature)466 arg_count_for_signature(const char *signature)
467 {
468 	int count = 0;
469 	for(; *signature; ++signature) {
470 		switch(*signature) {
471 		case 'i':
472 		case 'u':
473 		case 'f':
474 		case 's':
475 		case 'o':
476 		case 'n':
477 		case 'a':
478 		case 'h':
479 			++count;
480 		}
481 	}
482 	return count;
483 }
484 
485 int
wl_message_get_since(const struct wl_message * message)486 wl_message_get_since(const struct wl_message *message)
487 {
488 	int since;
489 
490 	since = atoi(message->signature);
491 
492 	if (since == 0)
493 		since = 1;
494 
495 	return since;
496 }
497 
498 void
wl_argument_from_va_list(const char * signature,union wl_argument * args,int count,va_list ap)499 wl_argument_from_va_list(const char *signature, union wl_argument *args,
500 			 int count, va_list ap)
501 {
502 	int i;
503 	const char *sig_iter;
504 	struct argument_details arg;
505 
506 	sig_iter = signature;
507 	for (i = 0; i < count; i++) {
508 		sig_iter = get_next_argument(sig_iter, &arg);
509 
510 		switch(arg.type) {
511 		case 'i':
512 			args[i].i = va_arg(ap, int32_t);
513 			break;
514 		case 'u':
515 			args[i].u = va_arg(ap, uint32_t);
516 			break;
517 		case 'f':
518 			args[i].f = va_arg(ap, wl_fixed_t);
519 			break;
520 		case 's':
521 			args[i].s = va_arg(ap, const char *);
522 			break;
523 		case 'o':
524 			args[i].o = va_arg(ap, struct wl_object *);
525 			break;
526 		case 'n':
527 			args[i].o = va_arg(ap, struct wl_object *);
528 			break;
529 		case 'a':
530 			args[i].a = va_arg(ap, struct wl_array *);
531 			break;
532 		case 'h':
533 			args[i].h = va_arg(ap, int32_t);
534 			break;
535 		case '\0':
536 			return;
537 		}
538 	}
539 }
540 
541 static void
wl_closure_clear_fds(struct wl_closure * closure)542 wl_closure_clear_fds(struct wl_closure *closure)
543 {
544 	const char *signature = closure->message->signature;
545 	struct argument_details arg;
546 	int i;
547 
548 	for (i = 0; i < closure->count; i++) {
549 		signature = get_next_argument(signature, &arg);
550 		if (arg.type == 'h')
551 			closure->args[i].h = -1;
552 	}
553 }
554 
555 static struct wl_closure *
wl_closure_init(const struct wl_message * message,uint32_t size,int * num_arrays,union wl_argument * args)556 wl_closure_init(const struct wl_message *message, uint32_t size,
557                 int *num_arrays, union wl_argument *args)
558 {
559 	struct wl_closure *closure;
560 	int count;
561 
562 	count = arg_count_for_signature(message->signature);
563 	if (count > WL_CLOSURE_MAX_ARGS) {
564 		wl_log("too many args (%d)\n", count);
565 		errno = EINVAL;
566 		return NULL;
567 	}
568 
569 	if (size) {
570 		*num_arrays = wl_message_count_arrays(message);
571 		closure = malloc(sizeof *closure + size +
572 				 *num_arrays * sizeof(struct wl_array));
573 	} else {
574 		closure = malloc(sizeof *closure);
575 	}
576 
577 	if (!closure) {
578 		errno = ENOMEM;
579 		return NULL;
580 	}
581 
582 	if (args)
583 		memcpy(closure->args, args, count * sizeof *args);
584 
585 	closure->message = message;
586 	closure->count = count;
587 
588 	/* Set these all to -1 so we can close any that have been
589 	 * set to a real value during wl_closure_destroy().
590 	 * We may have copied a bunch of fds into the closure with
591 	 * memcpy previously, but those are undup()d client fds
592 	 * that we would have replaced anyway.
593 	 */
594 	wl_closure_clear_fds(closure);
595 
596 	return closure;
597 }
598 
599 struct wl_closure *
wl_closure_marshal(struct wl_object * sender,uint32_t opcode,union wl_argument * args,const struct wl_message * message)600 wl_closure_marshal(struct wl_object *sender, uint32_t opcode,
601 		   union wl_argument *args,
602 		   const struct wl_message *message)
603 {
604 	struct wl_closure *closure;
605 	struct wl_object *object;
606 	int i, count, fd, dup_fd;
607 	const char *signature;
608 	struct argument_details arg;
609 
610 	closure = wl_closure_init(message, 0, NULL, args);
611 	if (closure == NULL)
612 		return NULL;
613 
614 	count = closure->count;
615 
616 	signature = message->signature;
617 	for (i = 0; i < count; i++) {
618 		signature = get_next_argument(signature, &arg);
619 
620 		switch (arg.type) {
621 		case 'f':
622 		case 'u':
623 		case 'i':
624 			break;
625 		case 's':
626 			if (!arg.nullable && args[i].s == NULL)
627 				goto err_null;
628 			break;
629 		case 'o':
630 			if (!arg.nullable && args[i].o == NULL)
631 				goto err_null;
632 			break;
633 		case 'n':
634 			object = args[i].o;
635 			if (!arg.nullable && object == NULL)
636 				goto err_null;
637 
638 			closure->args[i].n = object ? object->id : 0;
639 			break;
640 		case 'a':
641 			if (!arg.nullable && args[i].a == NULL)
642 				goto err_null;
643 			break;
644 		case 'h':
645 			fd = args[i].h;
646 			dup_fd = wl_os_dupfd_cloexec(fd, 0);
647 			if (dup_fd < 0)
648 				wl_abort("dup failed: %s\n", strerror(errno));
649 			closure->args[i].h = dup_fd;
650 			break;
651 		default:
652 			wl_abort("unhandled format code: '%c'\n", arg.type);
653 			break;
654 		}
655 	}
656 
657 	closure->sender_id = sender->id;
658 	closure->opcode = opcode;
659 
660 	return closure;
661 
662 err_null:
663 	wl_closure_destroy(closure);
664 	wl_log("error marshalling arguments for %s (signature %s): "
665 	       "null value passed for arg %i\n", message->name,
666 	       message->signature, i);
667 	errno = EINVAL;
668 	return NULL;
669 }
670 
671 struct wl_closure *
wl_closure_vmarshal(struct wl_object * sender,uint32_t opcode,va_list ap,const struct wl_message * message)672 wl_closure_vmarshal(struct wl_object *sender, uint32_t opcode, va_list ap,
673 		    const struct wl_message *message)
674 {
675 	union wl_argument args[WL_CLOSURE_MAX_ARGS];
676 
677 	wl_argument_from_va_list(message->signature, args,
678 				 WL_CLOSURE_MAX_ARGS, ap);
679 
680 	return wl_closure_marshal(sender, opcode, args, message);
681 }
682 
683 struct wl_closure *
wl_connection_demarshal(struct wl_connection * connection,uint32_t size,struct wl_map * objects,const struct wl_message * message)684 wl_connection_demarshal(struct wl_connection *connection,
685 			uint32_t size,
686 			struct wl_map *objects,
687 			const struct wl_message *message)
688 {
689 	uint32_t *p, *next, *end, length, length_in_u32, id;
690 	int fd;
691 	char *s;
692 	int i, count, num_arrays;
693 	const char *signature;
694 	struct argument_details arg;
695 	struct wl_closure *closure;
696 	struct wl_array *array_extra;
697 
698 	/* Space for sender_id and opcode */
699 	if (size < 2 * sizeof *p) {
700 		wl_log("message too short, invalid header\n");
701 		wl_connection_consume(connection, size);
702 		errno = EINVAL;
703 		return NULL;
704 	}
705 
706 	closure = wl_closure_init(message, size, &num_arrays, NULL);
707 	if (closure == NULL) {
708 		wl_connection_consume(connection, size);
709 		return NULL;
710 	}
711 
712 	count = closure->count;
713 
714 	array_extra = closure->extra;
715 	p = (uint32_t *)(closure->extra + num_arrays);
716 	end = p + size / sizeof *p;
717 
718 	wl_connection_copy(connection, p, size);
719 	closure->sender_id = *p++;
720 	closure->opcode = *p++ & 0x0000ffff;
721 
722 	signature = message->signature;
723 	for (i = 0; i < count; i++) {
724 		signature = get_next_argument(signature, &arg);
725 
726 		if (arg.type != 'h' && p + 1 > end) {
727 			wl_log("message too short, "
728 			       "object (%d), message %s(%s)\n",
729 			       closure->sender_id, message->name,
730 			       message->signature);
731 			errno = EINVAL;
732 			goto err;
733 		}
734 
735 		switch (arg.type) {
736 		case 'u':
737 			closure->args[i].u = *p++;
738 			break;
739 		case 'i':
740 			closure->args[i].i = *p++;
741 			break;
742 		case 'f':
743 			closure->args[i].f = *p++;
744 			break;
745 		case 's':
746 			length = *p++;
747 
748 			if (length == 0) {
749 				closure->args[i].s = NULL;
750 				break;
751 			}
752 
753 			length_in_u32 = div_roundup(length, sizeof *p);
754 			if ((uint32_t) (end - p) < length_in_u32) {
755 				wl_log("message too short, "
756 				       "object (%d), message %s(%s)\n",
757 				       closure->sender_id, message->name,
758 				       message->signature);
759 				errno = EINVAL;
760 				goto err;
761 			}
762 			next = p + length_in_u32;
763 
764 			s = (char *) p;
765 
766 			if (length > 0 && s[length - 1] != '\0') {
767 				wl_log("string not nul-terminated, "
768 				       "message %s(%s)\n",
769 				       message->name, message->signature);
770 				errno = EINVAL;
771 				goto err;
772 			}
773 
774 			closure->args[i].s = s;
775 			p = next;
776 			break;
777 		case 'o':
778 			id = *p++;
779 			closure->args[i].n = id;
780 
781 			if (id == 0 && !arg.nullable) {
782 				wl_log("NULL object received on non-nullable "
783 				       "type, message %s(%s)\n", message->name,
784 				       message->signature);
785 				errno = EINVAL;
786 				goto err;
787 			}
788 			break;
789 		case 'n':
790 			id = *p++;
791 			closure->args[i].n = id;
792 
793 			if (id == 0 && !arg.nullable) {
794 				wl_log("NULL new ID received on non-nullable "
795 				       "type, message %s(%s)\n", message->name,
796 				       message->signature);
797 				errno = EINVAL;
798 				goto err;
799 			}
800 
801 			if (wl_map_reserve_new(objects, id) < 0) {
802 				wl_log("not a valid new object id (%u), "
803 				       "message %s(%s)\n",
804 				       id, message->name, message->signature);
805 				errno = EINVAL;
806 				goto err;
807 			}
808 
809 			break;
810 		case 'a':
811 			length = *p++;
812 
813 			length_in_u32 = div_roundup(length, sizeof *p);
814 			if ((uint32_t) (end - p) < length_in_u32) {
815 				wl_log("message too short, "
816 				       "object (%d), message %s(%s)\n",
817 				       closure->sender_id, message->name,
818 				       message->signature);
819 				errno = EINVAL;
820 				goto err;
821 			}
822 			next = p + length_in_u32;
823 
824 			array_extra->size = length;
825 			array_extra->alloc = 0;
826 			array_extra->data = p;
827 
828 			closure->args[i].a = array_extra++;
829 			p = next;
830 			break;
831 		case 'h':
832 			if (connection->fds_in.tail == connection->fds_in.head) {
833 				wl_log("file descriptor expected, "
834 				       "object (%d), message %s(%s)\n",
835 				       closure->sender_id, message->name,
836 				       message->signature);
837 				errno = EINVAL;
838 				goto err;
839 			}
840 
841 			wl_buffer_copy(&connection->fds_in, &fd, sizeof fd);
842 			connection->fds_in.tail += sizeof fd;
843 			closure->args[i].h = fd;
844 			break;
845 		default:
846 			wl_abort("unknown type\n");
847 			break;
848 		}
849 	}
850 
851 	wl_connection_consume(connection, size);
852 
853 	return closure;
854 
855  err:
856 	wl_closure_destroy(closure);
857 	wl_connection_consume(connection, size);
858 
859 	return NULL;
860 }
861 
862 bool
wl_object_is_zombie(struct wl_map * map,uint32_t id)863 wl_object_is_zombie(struct wl_map *map, uint32_t id)
864 {
865 	uint32_t flags;
866 
867 	/* Zombie objects only exist on the client side. */
868 	if (map->side == WL_MAP_SERVER_SIDE)
869 		return false;
870 
871 	/* Zombie objects can only have been created by the client. */
872 	if (id >= WL_SERVER_ID_START)
873 		return false;
874 
875 	flags = wl_map_lookup_flags(map, id);
876 	return !!(flags & WL_MAP_ENTRY_ZOMBIE);
877 }
878 
879 int
wl_closure_lookup_objects(struct wl_closure * closure,struct wl_map * objects)880 wl_closure_lookup_objects(struct wl_closure *closure, struct wl_map *objects)
881 {
882 	struct wl_object *object;
883 	const struct wl_message *message;
884 	const char *signature;
885 	struct argument_details arg;
886 	int i, count;
887 	uint32_t id;
888 
889 	message = closure->message;
890 	signature = message->signature;
891 	count = arg_count_for_signature(signature);
892 	for (i = 0; i < count; i++) {
893 		signature = get_next_argument(signature, &arg);
894 		switch (arg.type) {
895 		case 'o':
896 			id = closure->args[i].n;
897 			closure->args[i].o = NULL;
898 
899 			object = wl_map_lookup(objects, id);
900 			if (wl_object_is_zombie(objects, id)) {
901 				/* references object we've already
902 				 * destroyed client side */
903 				object = NULL;
904 			} else if (object == NULL && id != 0) {
905 				wl_log("unknown object (%u), message %s(%s)\n",
906 				       id, message->name, message->signature);
907 				errno = EINVAL;
908 				return -1;
909 			}
910 
911 			if (object != NULL && message->types[i] != NULL &&
912 			    !wl_interface_equal((object)->interface,
913 						message->types[i])) {
914 				wl_log("invalid object (%u), type (%s), "
915 				       "message %s(%s)\n",
916 				       id, (object)->interface->name,
917 				       message->name, message->signature);
918 				errno = EINVAL;
919 				return -1;
920 			}
921 			closure->args[i].o = object;
922 		}
923 	}
924 
925 	return 0;
926 }
927 
928 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)929 convert_arguments_to_ffi(const char *signature, uint32_t flags,
930 			 union wl_argument *args,
931 			 int count, ffi_type **ffi_types, void** ffi_args)
932 {
933 	int i;
934 	const char *sig_iter;
935 	struct argument_details arg;
936 
937 	sig_iter = signature;
938 	for (i = 0; i < count; i++) {
939 		sig_iter = get_next_argument(sig_iter, &arg);
940 
941 		switch(arg.type) {
942 		case 'i':
943 			ffi_types[i] = &ffi_type_sint32;
944 			ffi_args[i] = &args[i].i;
945 			break;
946 		case 'u':
947 			ffi_types[i] = &ffi_type_uint32;
948 			ffi_args[i] = &args[i].u;
949 			break;
950 		case 'f':
951 			ffi_types[i] = &ffi_type_sint32;
952 			ffi_args[i] = &args[i].f;
953 			break;
954 		case 's':
955 			ffi_types[i] = &ffi_type_pointer;
956 			ffi_args[i] = &args[i].s;
957 			break;
958 		case 'o':
959 			ffi_types[i] = &ffi_type_pointer;
960 			ffi_args[i] = &args[i].o;
961 			break;
962 		case 'n':
963 			if (flags & WL_CLOSURE_INVOKE_CLIENT) {
964 				ffi_types[i] = &ffi_type_pointer;
965 				ffi_args[i] = &args[i].o;
966 			} else {
967 				ffi_types[i] = &ffi_type_uint32;
968 				ffi_args[i] = &args[i].n;
969 			}
970 			break;
971 		case 'a':
972 			ffi_types[i] = &ffi_type_pointer;
973 			ffi_args[i] = &args[i].a;
974 			break;
975 		case 'h':
976 			ffi_types[i] = &ffi_type_sint32;
977 			ffi_args[i] = &args[i].h;
978 			break;
979 		default:
980 			wl_abort("unknown type\n");
981 			break;
982 		}
983 	}
984 }
985 
986 void
wl_closure_invoke(struct wl_closure * closure,uint32_t flags,struct wl_object * target,uint32_t opcode,void * data)987 wl_closure_invoke(struct wl_closure *closure, uint32_t flags,
988 		  struct wl_object *target, uint32_t opcode, void *data)
989 {
990 	int count;
991 	ffi_cif cif;
992 	ffi_type *ffi_types[WL_CLOSURE_MAX_ARGS + 2];
993 	void * ffi_args[WL_CLOSURE_MAX_ARGS + 2];
994 	void (* const *implementation)(void);
995 
996 	count = arg_count_for_signature(closure->message->signature);
997 
998 	ffi_types[0] = &ffi_type_pointer;
999 	ffi_args[0] = &data;
1000 	ffi_types[1] = &ffi_type_pointer;
1001 	ffi_args[1] = &target;
1002 
1003 	convert_arguments_to_ffi(closure->message->signature, flags, closure->args,
1004 				 count, ffi_types + 2, ffi_args + 2);
1005 
1006 	ffi_prep_cif(&cif, FFI_DEFAULT_ABI,
1007 		     count + 2, &ffi_type_void, ffi_types);
1008 
1009 	implementation = target->implementation;
1010 	if (!implementation[opcode]) {
1011 		wl_abort("listener function for opcode %u of %s is NULL\n",
1012 			 opcode, target->interface->name);
1013 	}
1014 	ffi_call(&cif, implementation[opcode], NULL, ffi_args);
1015 
1016 	wl_closure_clear_fds(closure);
1017 }
1018 
1019 void
wl_closure_dispatch(struct wl_closure * closure,wl_dispatcher_func_t dispatcher,struct wl_object * target,uint32_t opcode)1020 wl_closure_dispatch(struct wl_closure *closure, wl_dispatcher_func_t dispatcher,
1021 		    struct wl_object *target, uint32_t opcode)
1022 {
1023 	dispatcher(target->implementation, target, opcode, closure->message,
1024 		   closure->args);
1025 
1026 	wl_closure_clear_fds(closure);
1027 }
1028 
1029 static int
copy_fds_to_connection(struct wl_closure * closure,struct wl_connection * connection)1030 copy_fds_to_connection(struct wl_closure *closure,
1031 		       struct wl_connection *connection)
1032 {
1033 	const struct wl_message *message = closure->message;
1034 	uint32_t i, count;
1035 	struct argument_details arg;
1036 	const char *signature = message->signature;
1037 	int fd;
1038 
1039 	count = arg_count_for_signature(signature);
1040 	for (i = 0; i < count; i++) {
1041 		signature = get_next_argument(signature, &arg);
1042 		if (arg.type != 'h')
1043 			continue;
1044 
1045 		fd = closure->args[i].h;
1046 		if (wl_connection_put_fd(connection, fd)) {
1047 			wl_log("request could not be marshaled: "
1048 			       "can't send file descriptor");
1049 			return -1;
1050 		}
1051 		closure->args[i].h = -1;
1052 	}
1053 
1054 	return 0;
1055 }
1056 
1057 
1058 static uint32_t
buffer_size_for_closure(struct wl_closure * closure)1059 buffer_size_for_closure(struct wl_closure *closure)
1060 {
1061 	const struct wl_message *message = closure->message;
1062 	int i, count;
1063 	struct argument_details arg;
1064 	const char *signature;
1065 	uint32_t size, buffer_size = 0;
1066 
1067 	signature = message->signature;
1068 	count = arg_count_for_signature(signature);
1069 	for (i = 0; i < count; i++) {
1070 		signature = get_next_argument(signature, &arg);
1071 
1072 		switch (arg.type) {
1073 		case 'h':
1074 			break;
1075 		case 'u':
1076 		case 'i':
1077 		case 'f':
1078 		case 'o':
1079 		case 'n':
1080 			buffer_size++;
1081 			break;
1082 		case 's':
1083 			if (closure->args[i].s == NULL) {
1084 				buffer_size++;
1085 				break;
1086 			}
1087 
1088 			size = strlen(closure->args[i].s) + 1;
1089 			buffer_size += 1 + div_roundup(size, sizeof(uint32_t));
1090 			break;
1091 		case 'a':
1092 			if (closure->args[i].a == NULL) {
1093 				buffer_size++;
1094 				break;
1095 			}
1096 
1097 			size = closure->args[i].a->size;
1098 			buffer_size += (1 + div_roundup(size, sizeof(uint32_t)));
1099 			break;
1100 		default:
1101 			break;
1102 		}
1103 	}
1104 
1105 	return buffer_size + 2;
1106 }
1107 
1108 static int
serialize_closure(struct wl_closure * closure,uint32_t * buffer,size_t buffer_count)1109 serialize_closure(struct wl_closure *closure, uint32_t *buffer,
1110 		  size_t buffer_count)
1111 {
1112 	const struct wl_message *message = closure->message;
1113 	unsigned int i, count, size;
1114 	uint32_t *p, *end;
1115 	struct argument_details arg;
1116 	const char *signature;
1117 
1118 	if (buffer_count < 2)
1119 		goto overflow;
1120 
1121 	p = buffer + 2;
1122 	end = buffer + buffer_count;
1123 
1124 	signature = message->signature;
1125 	count = arg_count_for_signature(signature);
1126 	for (i = 0; i < count; i++) {
1127 		signature = get_next_argument(signature, &arg);
1128 
1129 		if (arg.type == 'h')
1130 			continue;
1131 
1132 		if (p + 1 > end)
1133 			goto overflow;
1134 
1135 		switch (arg.type) {
1136 		case 'u':
1137 			*p++ = closure->args[i].u;
1138 			break;
1139 		case 'i':
1140 			*p++ = closure->args[i].i;
1141 			break;
1142 		case 'f':
1143 			*p++ = closure->args[i].f;
1144 			break;
1145 		case 'o':
1146 			*p++ = closure->args[i].o ? closure->args[i].o->id : 0;
1147 			break;
1148 		case 'n':
1149 			*p++ = closure->args[i].n;
1150 			break;
1151 		case 's':
1152 			if (closure->args[i].s == NULL) {
1153 				*p++ = 0;
1154 				break;
1155 			}
1156 
1157 			size = strlen(closure->args[i].s) + 1;
1158 			*p++ = size;
1159 
1160 			if (p + div_roundup(size, sizeof *p) > end)
1161 				goto overflow;
1162 
1163 			memcpy(p, closure->args[i].s, size);
1164 			p += div_roundup(size, sizeof *p);
1165 			break;
1166 		case 'a':
1167 			if (closure->args[i].a == NULL) {
1168 				*p++ = 0;
1169 				break;
1170 			}
1171 
1172 			size = closure->args[i].a->size;
1173 			*p++ = size;
1174 
1175 			if (p + div_roundup(size, sizeof *p) > end)
1176 				goto overflow;
1177 
1178 			memcpy(p, closure->args[i].a->data, size);
1179 			p += div_roundup(size, sizeof *p);
1180 			break;
1181 		default:
1182 			break;
1183 		}
1184 	}
1185 
1186 	size = (p - buffer) * sizeof *p;
1187 
1188 	buffer[0] = closure->sender_id;
1189 	buffer[1] = size << 16 | (closure->opcode & 0x0000ffff);
1190 
1191 	return size;
1192 
1193 overflow:
1194 	errno = ERANGE;
1195 	return -1;
1196 }
1197 
1198 int
wl_closure_send(struct wl_closure * closure,struct wl_connection * connection)1199 wl_closure_send(struct wl_closure *closure, struct wl_connection *connection)
1200 {
1201 	int size;
1202 	uint32_t buffer_size;
1203 	uint32_t *buffer;
1204 	int result;
1205 
1206 	if (copy_fds_to_connection(closure, connection))
1207 		return -1;
1208 
1209 	buffer_size = buffer_size_for_closure(closure);
1210 	buffer = zalloc(buffer_size * sizeof buffer[0]);
1211 	if (buffer == NULL)
1212 		return -1;
1213 
1214 	size = serialize_closure(closure, buffer, buffer_size);
1215 	if (size < 0) {
1216 		free(buffer);
1217 		return -1;
1218 	}
1219 
1220 	result = wl_connection_write(connection, buffer, size);
1221 	free(buffer);
1222 
1223 	return result;
1224 }
1225 
1226 int
wl_closure_queue(struct wl_closure * closure,struct wl_connection * connection)1227 wl_closure_queue(struct wl_closure *closure, struct wl_connection *connection)
1228 {
1229 	int size;
1230 	uint32_t buffer_size;
1231 	uint32_t *buffer;
1232 	int result;
1233 
1234 	if (copy_fds_to_connection(closure, connection))
1235 		return -1;
1236 
1237 	buffer_size = buffer_size_for_closure(closure);
1238 	buffer = malloc(buffer_size * sizeof buffer[0]);
1239 	if (buffer == NULL)
1240 		return -1;
1241 
1242 	size = serialize_closure(closure, buffer, buffer_size);
1243 	if (size < 0) {
1244 		free(buffer);
1245 		return -1;
1246 	}
1247 
1248 	result = wl_connection_queue(connection, buffer, size);
1249 	free(buffer);
1250 
1251 	return result;
1252 }
1253 
1254 struct closure_buffer_info {
1255 	char *buffer;
1256 	size_t buffer_size;
1257 	size_t offset;
1258 };
1259 
1260 static void
asnprintf(struct closure_buffer_info * buffer_info,const char * fmt,...)1261 asnprintf(struct closure_buffer_info *buffer_info, const char *fmt, ...)
1262 {
1263 	va_list args;
1264 	int written;
1265 	char *buffer = buffer_info->buffer + buffer_info->offset;
1266 	size_t size = 0;
1267 
1268 	if (buffer_info->buffer_size)
1269 		size = buffer_info->buffer_size - buffer_info->offset;
1270 
1271 	va_start(args, fmt);
1272 	written = vsnprintf(buffer, size, fmt, args);
1273 	va_end(args);
1274 
1275 	if (buffer_info->buffer_size && (size_t) written > size)
1276 		written = (int) size;
1277 
1278 	if (written > 0)
1279 		buffer_info->offset += written;
1280 }
1281 
1282 static size_t
wl_closure_format_to_buffer(struct closure_buffer_info * buffer_info,struct wl_closure * closure,struct wl_object * target,int send,unsigned int time)1283 wl_closure_format_to_buffer(struct closure_buffer_info *buffer_info,
1284 		struct wl_closure *closure, struct wl_object *target, int send,
1285 		unsigned int time)
1286 {
1287 	int i;
1288 	struct argument_details arg;
1289 	const char *signature = closure->message->signature;
1290 
1291 	asnprintf(buffer_info, "[%10.3f] %s%s@%u.%s(",
1292 		time / 1000.0,
1293 		send ? " -> " : "",
1294 		target->interface->name, target->id,
1295 		closure->message->name);
1296 
1297 	for (i = 0; i < closure->count; i++) {
1298 		signature = get_next_argument(signature, &arg);
1299 		if (i > 0)
1300 			asnprintf(buffer_info, ", ");
1301 
1302 		switch (arg.type) {
1303 		case 'u':
1304 			asnprintf(buffer_info, "%u", closure->args[i].u);
1305 			break;
1306 		case 'i':
1307 			asnprintf(buffer_info, "%d", closure->args[i].i);
1308 			break;
1309 		case 'f':
1310 			asnprintf(buffer_info, "%f",
1311 				wl_fixed_to_double(closure->args[i].f));
1312 			break;
1313 		case 's':
1314 			if (closure->args[i].s)
1315 				asnprintf(buffer_info, "\"%s\"", closure->args[i].s);
1316 			else
1317 				asnprintf(buffer_info, "nil");
1318 			break;
1319 		case 'o':
1320 			if (closure->args[i].o)
1321 				asnprintf(buffer_info, "%s@%u",
1322 						closure->args[i].o->interface->name,
1323 						closure->args[i].o->id);
1324 			else
1325 				asnprintf(buffer_info, "nil");
1326 			break;
1327 		case 'n':
1328 			asnprintf(buffer_info, "new id %s@",
1329 					(closure->message->types[i]) ?
1330 					closure->message->types[i]->name :
1331 					"[unknown]");
1332 			if (closure->args[i].n != 0)
1333 				asnprintf(buffer_info, "%u", closure->args[i].n);
1334 			else
1335 				asnprintf(buffer_info, "nil");
1336 			break;
1337 		case 'a':
1338 			asnprintf(buffer_info, "array");
1339 			break;
1340 		case 'h':
1341 			asnprintf(buffer_info, "fd %d", closure->args[i].h);
1342 			break;
1343 		}
1344 	}
1345 
1346 	asnprintf(buffer_info, ")\n");
1347 	return buffer_info->offset;
1348 }
1349 
1350 void
wl_closure_print(struct wl_closure * closure,struct wl_object * target,int send)1351 wl_closure_print(struct wl_closure *closure, struct wl_object *target, int send)
1352 {
1353 	struct timespec tp;
1354 	unsigned int time;
1355 	char *buffer;
1356 	size_t buffer_size;
1357 	struct closure_buffer_info buffer_info;
1358 
1359 	clock_gettime(CLOCK_REALTIME, &tp);
1360 	time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
1361 	// For the first call, pass NULL for the buffer and zero for the size.
1362 	buffer_info.buffer = NULL;
1363 	buffer_info.buffer_size = 0;
1364 	buffer_info.offset = 0;
1365 	buffer_size = wl_closure_format_to_buffer(&buffer_info, closure, target,
1366 		send, time);
1367 	buffer = malloc(buffer_size * sizeof(char));
1368 	if (buffer == NULL) {
1369 		wl_log("[%10.3f] %s%s@%u.%s(%s)\n",
1370 			time / 1000.0,
1371 			send ? " -> " : "",
1372 			target->interface->name, target->id,
1373 			closure->message->name,
1374 			"Error allocating buffer for the log message");
1375 		return;
1376 	}
1377 	buffer_info.buffer = buffer;
1378 	buffer_info.buffer_size = buffer_size;
1379 	buffer_info.offset = 0;
1380 	wl_closure_format_to_buffer(&buffer_info, closure, target, send, time);
1381 	wl_log("%s", buffer);
1382 	free(buffer);
1383 }
1384 
1385 static int
wl_closure_close_fds(struct wl_closure * closure)1386 wl_closure_close_fds(struct wl_closure *closure)
1387 {
1388 	int i;
1389 	struct argument_details arg;
1390 	const char *signature = closure->message->signature;
1391 
1392 	for (i = 0; i < closure->count; i++) {
1393 		signature = get_next_argument(signature, &arg);
1394 		if (arg.type == 'h' && closure->args[i].h != -1)
1395 			close(closure->args[i].h);
1396 	}
1397 
1398 	return 0;
1399 }
1400 
1401 void
wl_closure_destroy(struct wl_closure * closure)1402 wl_closure_destroy(struct wl_closure *closure)
1403 {
1404 	/* wl_closure_destroy has free() semantics */
1405 	if (!closure)
1406 		return;
1407 
1408 	wl_closure_close_fds(closure);
1409 	free(closure);
1410 }
1411