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] = ⌖
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