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