Introduce lttng_domain_type_str utility
[lttng-tools.git] / src / common / unix.c
1 /*
2 * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
3 * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 *
7 */
8
9 #define _LGPL_SOURCE
10 #include <assert.h>
11 #include <limits.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <sys/stat.h>
16 #include <sys/types.h>
17 #include <unistd.h>
18 #include <errno.h>
19
20 #include <common/common.h>
21 #include <common/sessiond-comm/sessiond-comm.h>
22 #include <common/fd-handle.h>
23
24 #include "unix.h"
25
26 /*
27 * Connect to unix socket using the path name.
28 */
29 LTTNG_HIDDEN
30 int lttcomm_connect_unix_sock(const char *pathname)
31 {
32 struct sockaddr_un s_un;
33 int fd, ret, closeret;
34
35 if (strlen(pathname) >= sizeof(s_un.sun_path)) {
36 ERR("unix socket address (\"%s\") is longer than the platform's limit (%zu > %zu).",
37 pathname, strlen(pathname) + 1,
38 sizeof(s_un.sun_path));
39 ret = -ENAMETOOLONG;
40 goto error;
41 }
42
43 fd = socket(PF_UNIX, SOCK_STREAM, 0);
44 if (fd < 0) {
45 PERROR("socket");
46 ret = fd;
47 goto error;
48 }
49
50 memset(&s_un, 0, sizeof(s_un));
51 s_un.sun_family = AF_UNIX;
52 strncpy(s_un.sun_path, pathname, sizeof(s_un.sun_path));
53 s_un.sun_path[sizeof(s_un.sun_path) - 1] = '\0';
54
55 ret = connect(fd, (struct sockaddr *) &s_un, sizeof(s_un));
56 if (ret < 0) {
57 /*
58 * Don't print message on connect error, because connect is used in
59 * normal execution to detect if sessiond is alive.
60 */
61 goto error_connect;
62 }
63
64 return fd;
65
66 error_connect:
67 closeret = close(fd);
68 if (closeret) {
69 PERROR("close");
70 }
71 error:
72 return ret;
73 }
74
75 /*
76 * Do an accept(2) on the sock and return the new file descriptor. The socket
77 * MUST be bind(2) before.
78 */
79 LTTNG_HIDDEN
80 int lttcomm_accept_unix_sock(int sock)
81 {
82 int new_fd;
83 struct sockaddr_un s_un;
84 socklen_t len = sizeof(s_un);
85
86 /* Blocking call */
87 new_fd = accept(sock, (struct sockaddr *) &s_un, &len);
88 if (new_fd < 0) {
89 PERROR("accept");
90 }
91
92 return new_fd;
93 }
94
95 LTTNG_HIDDEN
96 int lttcomm_create_anon_unix_socketpair(int *fds)
97 {
98 if (socketpair(PF_UNIX, SOCK_STREAM, 0, fds) < 0) {
99 PERROR("socketpair");
100 return -1;
101 }
102 return 0;
103 }
104
105 /*
106 * Creates a AF_UNIX local socket using pathname bind the socket upon creation
107 * and return the fd.
108 */
109 LTTNG_HIDDEN
110 int lttcomm_create_unix_sock(const char *pathname)
111 {
112 struct sockaddr_un s_un;
113 int fd = -1;
114 int ret = -1;
115
116 if (strlen(pathname) >= sizeof(s_un.sun_path)) {
117 ERR("unix socket address (\"%s\") is longer than the platform's limit (%zu > %zu).",
118 pathname, strlen(pathname) + 1,
119 sizeof(s_un.sun_path));
120 ret = -ENAMETOOLONG;
121 goto error;
122 }
123
124 /* Create server socket */
125 if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
126 PERROR("socket");
127 goto error;
128 }
129
130 memset(&s_un, 0, sizeof(s_un));
131 s_un.sun_family = AF_UNIX;
132 strncpy(s_un.sun_path, pathname, sizeof(s_un.sun_path));
133 s_un.sun_path[sizeof(s_un.sun_path) - 1] = '\0';
134
135 /* Unlink the old file if present */
136 (void) unlink(pathname);
137 ret = bind(fd, (struct sockaddr *) &s_un, sizeof(s_un));
138 if (ret < 0) {
139 PERROR("bind");
140 goto error;
141 }
142
143 return fd;
144
145 error:
146 if (fd >= 0) {
147 if (close(fd) < 0) {
148 PERROR("close create unix sock");
149 }
150 }
151 return ret;
152 }
153
154 /*
155 * Make the socket listen using LTTNG_SESSIOND_COMM_MAX_LISTEN.
156 */
157 LTTNG_HIDDEN
158 int lttcomm_listen_unix_sock(int sock)
159 {
160 int ret;
161
162 ret = listen(sock, LTTNG_SESSIOND_COMM_MAX_LISTEN);
163 if (ret < 0) {
164 PERROR("listen");
165 }
166
167 return ret;
168 }
169
170 /*
171 * Receive data of size len in put that data into the buf param. Using recvmsg
172 * API.
173 *
174 * Return the size of received data.
175 */
176 LTTNG_HIDDEN
177 ssize_t lttcomm_recv_unix_sock(int sock, void *buf, size_t len)
178 {
179 struct msghdr msg;
180 struct iovec iov[1];
181 ssize_t ret = -1;
182 size_t len_last;
183
184 memset(&msg, 0, sizeof(msg));
185
186 iov[0].iov_base = buf;
187 iov[0].iov_len = len;
188 msg.msg_iov = iov;
189 msg.msg_iovlen = 1;
190
191 do {
192 len_last = iov[0].iov_len;
193 ret = lttng_recvmsg_nosigpipe(sock, &msg);
194 if (ret > 0) {
195 iov[0].iov_base += ret;
196 iov[0].iov_len -= ret;
197 assert(ret <= len_last);
198 }
199 } while ((ret > 0 && ret < len_last) || (ret < 0 && errno == EINTR));
200 if (ret < 0) {
201 PERROR("recvmsg");
202 } else if (ret > 0) {
203 ret = len;
204 }
205 /* Else ret = 0 meaning an orderly shutdown. */
206
207 return ret;
208 }
209
210 /*
211 * Receive data of size len in put that data into the buf param. Using recvmsg
212 * API. Only use with sockets set in non-blocking mode.
213 *
214 * NOTE: EPIPE errors are NOT reported. This call expects the socket to be in a
215 * poll set. The poll loop will handle the EPIPE original cause.
216 *
217 * Return the size of received data.
218 */
219 LTTNG_HIDDEN
220 ssize_t lttcomm_recv_unix_sock_non_block(int sock, void *buf, size_t len)
221 {
222 struct msghdr msg;
223 struct iovec iov[1];
224 ssize_t ret;
225
226 memset(&msg, 0, sizeof(msg));
227
228 iov[0].iov_base = buf;
229 iov[0].iov_len = len;
230 msg.msg_iov = iov;
231 msg.msg_iovlen = 1;
232
233 retry:
234 ret = lttng_recvmsg_nosigpipe(sock, &msg);
235 if (ret < 0) {
236 if (errno == EINTR) {
237 goto retry;
238 } else {
239 /*
240 * We consider EPIPE and EAGAIN/EWOULDBLOCK as expected.
241 */
242 if (errno == EAGAIN || errno == EWOULDBLOCK ||
243 errno == EPIPE) {
244 /*
245 * Nothing was recv.
246 */
247 ret = 0;
248 goto end;
249 }
250
251 /* Unexpected error */
252 PERROR("recvmsg");
253 ret = -1;
254 goto end;
255 }
256 }
257
258 end:
259 return ret;
260 }
261
262 /*
263 * Send buf data of size len. Using sendmsg API.
264 *
265 * Return the size of sent data.
266 */
267 LTTNG_HIDDEN
268 ssize_t lttcomm_send_unix_sock(int sock, const void *buf, size_t len)
269 {
270 struct msghdr msg;
271 struct iovec iov[1];
272 ssize_t ret;
273
274 memset(&msg, 0, sizeof(msg));
275
276 iov[0].iov_base = (void *) buf;
277 iov[0].iov_len = len;
278 msg.msg_iov = iov;
279 msg.msg_iovlen = 1;
280
281 while (iov[0].iov_len) {
282 ret = sendmsg(sock, &msg, 0);
283 if (ret < 0) {
284 if (errno == EINTR) {
285 continue;
286 } else {
287 /*
288 * Only warn about EPIPE when quiet mode is
289 * deactivated.
290 * We consider EPIPE as expected.
291 */
292 if (errno != EPIPE || !lttng_opt_quiet) {
293 PERROR("sendmsg");
294 }
295 goto end;
296 }
297 }
298 iov[0].iov_len -= ret;
299 iov[0].iov_base += ret;
300 }
301 ret = len;
302 end:
303 return ret;
304 }
305
306 /*
307 * Send buf data of size len. Using sendmsg API.
308 * Only use with non-blocking sockets. The difference with the blocking version
309 * of the function is that this one does not retry to send on partial sends,
310 * except if the interruption was caused by a signal (EINTR).
311 *
312 * NOTE: EPIPE errors are NOT reported. This call expects the socket to be in a
313 * poll set. The poll loop will handle the EPIPE original cause.
314 *
315 * Return the size of sent data.
316 */
317 LTTNG_HIDDEN
318 ssize_t lttcomm_send_unix_sock_non_block(int sock, const void *buf, size_t len)
319 {
320 struct msghdr msg;
321 struct iovec iov[1];
322 ssize_t ret;
323
324 memset(&msg, 0, sizeof(msg));
325
326 iov[0].iov_base = (void *) buf;
327 iov[0].iov_len = len;
328 msg.msg_iov = iov;
329 msg.msg_iovlen = 1;
330
331 retry:
332 ret = sendmsg(sock, &msg, 0);
333 if (ret < 0) {
334 if (errno == EINTR) {
335 goto retry;
336 } else {
337 /*
338 * We consider EPIPE and EAGAIN/EWOULDBLOCK as expected.
339 */
340 if (errno == EAGAIN || errno == EWOULDBLOCK ||
341 errno == EPIPE) {
342 /*
343 * This can happen in non blocking mode.
344 * Nothing was sent.
345 */
346 ret = 0;
347 goto end;
348 }
349
350 /* Unexpected error */
351 PERROR("sendmsg");
352 ret = -1;
353 goto end;
354 }
355 }
356 end:
357 return ret;
358 }
359
360 /*
361 * Shutdown cleanly a unix socket.
362 */
363 LTTNG_HIDDEN
364 int lttcomm_close_unix_sock(int sock)
365 {
366 int ret, closeret;
367
368 /* Shutdown receptions and transmissions */
369 ret = shutdown(sock, SHUT_RDWR);
370 if (ret < 0) {
371 PERROR("shutdown");
372 }
373
374 closeret = close(sock);
375 if (closeret) {
376 PERROR("close");
377 }
378
379 return ret;
380 }
381
382 /*
383 * Send a message accompanied by fd(s) over a unix socket.
384 *
385 * Returns the size of data sent, or negative error value.
386 */
387 LTTNG_HIDDEN
388 ssize_t lttcomm_send_fds_unix_sock(int sock, const int *fds, size_t nb_fd)
389 {
390 struct msghdr msg;
391 struct cmsghdr *cmptr;
392 struct iovec iov[1];
393 ssize_t ret = -1;
394 unsigned int sizeof_fds = nb_fd * sizeof(int);
395 char tmp[CMSG_SPACE(sizeof_fds)];
396 char dummy = 0;
397
398 memset(&msg, 0, sizeof(msg));
399 memset(tmp, 0, sizeof(tmp));
400
401 if (nb_fd > LTTCOMM_MAX_SEND_FDS)
402 return -EINVAL;
403
404 msg.msg_control = (caddr_t)tmp;
405 msg.msg_controllen = CMSG_LEN(sizeof_fds);
406
407 cmptr = CMSG_FIRSTHDR(&msg);
408 if (!cmptr) {
409 return -1;
410 }
411
412 cmptr->cmsg_level = SOL_SOCKET;
413 cmptr->cmsg_type = SCM_RIGHTS;
414 cmptr->cmsg_len = CMSG_LEN(sizeof_fds);
415 memcpy(CMSG_DATA(cmptr), fds, sizeof_fds);
416 /* Sum of the length of all control messages in the buffer: */
417 msg.msg_controllen = cmptr->cmsg_len;
418
419 iov[0].iov_base = &dummy;
420 iov[0].iov_len = 1;
421 msg.msg_iov = iov;
422 msg.msg_iovlen = 1;
423
424 do {
425 ret = sendmsg(sock, &msg, 0);
426 } while (ret < 0 && errno == EINTR);
427 if (ret < 0) {
428 /*
429 * Only warn about EPIPE when quiet mode is deactivated.
430 * We consider EPIPE as expected.
431 */
432 if (errno != EPIPE || !lttng_opt_quiet) {
433 PERROR("sendmsg");
434 }
435 }
436 return ret;
437 }
438
439 /*
440 * Send the fd(s) of a payload view over a unix socket.
441 *
442 * Returns the size of data sent, or negative error value.
443 */
444 static
445 ssize_t _lttcomm_send_payload_view_fds_unix_sock(int sock,
446 struct lttng_payload_view *view,
447 bool blocking)
448 {
449 int i;
450 ssize_t ret;
451 struct lttng_dynamic_array raw_fds;
452 const int fd_count = lttng_payload_view_get_fd_handle_count(view);
453
454 lttng_dynamic_array_init(&raw_fds, sizeof(int), NULL);
455
456 if (fd_count < 0) {
457 ret = -LTTNG_ERR_INVALID;
458 goto end;
459 }
460
461 /*
462 * Prepare a contiguous array of file descriptors to send them.
463 *
464 * Note that the reference to each fd is released during the iteration;
465 * we're just getting the numerical value of the fds to conform to the
466 * syscall's interface. We rely on the fact that "view" must remain
467 * valid for the duration of the call and that the underlying payload
468 * owns a reference to the fd_handles.
469 */
470 for (i = 0; i < fd_count; i++) {
471 struct fd_handle *handle =
472 lttng_payload_view_pop_fd_handle(view);
473 const int raw_fd = fd_handle_get_fd(handle);
474 const int add_ret = lttng_dynamic_array_add_element(
475 &raw_fds, &raw_fd);
476
477 fd_handle_put(handle);
478 if (add_ret) {
479 ret = -LTTNG_ERR_NOMEM;
480 goto end;
481 }
482 }
483
484 if (blocking) {
485 ret = lttcomm_send_fds_unix_sock(sock,
486 (const int *) raw_fds.buffer.data, fd_count);
487 } else {
488 ret = lttcomm_send_fds_unix_sock_non_block(sock,
489 (const int *) raw_fds.buffer.data, fd_count);
490 }
491
492 end:
493 lttng_dynamic_array_reset(&raw_fds);
494 return ret;
495 }
496
497 LTTNG_HIDDEN
498 ssize_t lttcomm_send_payload_view_fds_unix_sock(int sock,
499 struct lttng_payload_view *view)
500 {
501 return _lttcomm_send_payload_view_fds_unix_sock(sock, view, true);
502 }
503
504 LTTNG_HIDDEN
505 ssize_t lttcomm_send_payload_view_fds_unix_sock_non_block(int sock,
506 struct lttng_payload_view *view)
507 {
508 return _lttcomm_send_payload_view_fds_unix_sock(sock, view, false);
509 }
510
511 /*
512 * Send a message accompanied by fd(s) over a unix socket.
513 * Only use for non blocking socket.
514 *
515 * Returns the size of data sent, or negative error value.
516 */
517 LTTNG_HIDDEN
518 ssize_t lttcomm_send_fds_unix_sock_non_block(int sock, const int *fds, size_t nb_fd)
519 {
520 struct msghdr msg;
521 struct cmsghdr *cmptr;
522 struct iovec iov[1];
523 ssize_t ret = -1;
524 unsigned int sizeof_fds = nb_fd * sizeof(int);
525 char tmp[CMSG_SPACE(sizeof_fds)];
526 char dummy = 0;
527
528 memset(&msg, 0, sizeof(msg));
529 memset(tmp, 0, sizeof(tmp));
530
531 if (nb_fd > LTTCOMM_MAX_SEND_FDS)
532 return -EINVAL;
533
534 msg.msg_control = (caddr_t)tmp;
535 msg.msg_controllen = CMSG_LEN(sizeof_fds);
536
537 cmptr = CMSG_FIRSTHDR(&msg);
538 if (!cmptr) {
539 return -1;
540 }
541
542 cmptr->cmsg_level = SOL_SOCKET;
543 cmptr->cmsg_type = SCM_RIGHTS;
544 cmptr->cmsg_len = CMSG_LEN(sizeof_fds);
545 memcpy(CMSG_DATA(cmptr), fds, sizeof_fds);
546 /* Sum of the length of all control messages in the buffer: */
547 msg.msg_controllen = cmptr->cmsg_len;
548
549 iov[0].iov_base = &dummy;
550 iov[0].iov_len = 1;
551 msg.msg_iov = iov;
552 msg.msg_iovlen = 1;
553
554 retry:
555 ret = sendmsg(sock, &msg, 0);
556 if (ret < 0) {
557 if (errno == EINTR) {
558 goto retry;
559 } else {
560 /*
561 * We consider EPIPE and EAGAIN/EWOULDBLOCK as expected.
562 */
563 if (errno == EAGAIN || errno == EWOULDBLOCK) {
564 /*
565 * This can happen in non blocking mode.
566 * Nothing was sent.
567 */
568 ret = 0;
569 goto end;
570 }
571
572 if (errno == EPIPE) {
573 /* Expected error, pass error to caller */
574 DBG3("EPIPE on sendmsg");
575 ret = -1;
576 goto end;
577 }
578
579 /* Unexpected error */
580 PERROR("sendmsg");
581 ret = -1;
582 goto end;
583 }
584 }
585
586 end:
587 return ret;
588 }
589
590 /*
591 * Recv a message accompanied by fd(s) from a unix socket.
592 *
593 * Returns the size of received data, or negative error value.
594 *
595 * Expect at most "nb_fd" file descriptors. Returns the number of fd
596 * actually received in nb_fd.
597 */
598 LTTNG_HIDDEN
599 ssize_t lttcomm_recv_fds_unix_sock(int sock, int *fds, size_t nb_fd)
600 {
601 struct iovec iov[1];
602 ssize_t ret = 0;
603 struct cmsghdr *cmsg;
604 size_t sizeof_fds = nb_fd * sizeof(int);
605
606 #ifdef __linux__
607 /* Account for the struct ucred cmsg in the buffer size */
608 #define LTTNG_SOCK_RECV_FDS_BUF_SIZE CMSG_SPACE(sizeof_fds) + CMSG_SPACE(sizeof(struct ucred))
609 #else
610 #define LTTNG_SOCK_RECV_FDS_BUF_SIZE CMSG_SPACE(sizeof_fds)
611 #endif /* __linux__ */
612
613 char recv_buf[LTTNG_SOCK_RECV_FDS_BUF_SIZE];
614 struct msghdr msg;
615 char dummy;
616
617 memset(&msg, 0, sizeof(msg));
618
619 /* Prepare to receive the structures */
620 iov[0].iov_base = &dummy;
621 iov[0].iov_len = 1;
622 msg.msg_iov = iov;
623 msg.msg_iovlen = 1;
624
625 cmsg = (struct cmsghdr *) recv_buf;
626 cmsg->cmsg_len = CMSG_LEN(sizeof_fds);
627 cmsg->cmsg_level = SOL_SOCKET;
628 cmsg->cmsg_type = SCM_RIGHTS;
629
630 msg.msg_control = cmsg;
631 msg.msg_controllen = CMSG_LEN(sizeof(recv_buf));
632 msg.msg_flags = 0;
633
634 retry:
635 ret = lttng_recvmsg_nosigpipe(sock, &msg);
636 if (ret < 0) {
637 if (errno == EINTR) {
638 goto retry;
639 } else {
640 /* We consider EPIPE and EAGAIN as expected. */
641 if (!lttng_opt_quiet &&
642 (errno != EPIPE && errno != EAGAIN)) {
643 PERROR("recvmsg");
644 }
645 goto end;
646 }
647 }
648
649 if (ret != 1) {
650 fprintf(stderr, "Error: Received %zd bytes, expected %d\n",
651 ret, 1);
652 goto end;
653 }
654
655 if (msg.msg_flags & MSG_CTRUNC) {
656 fprintf(stderr, "Error: Control message truncated.\n");
657 ret = -1;
658 goto end;
659 }
660
661 /*
662 * If the socket was configured with SO_PASSCRED, the kernel will add a
663 * control message (cmsg) to the ancillary data of the unix socket. We
664 * need to expect a cmsg of the SCM_CREDENTIALS as the first control
665 * message.
666 */
667 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
668 if (cmsg->cmsg_level != SOL_SOCKET) {
669 fprintf(stderr, "Error: The socket needs to be of type SOL_SOCKET\n");
670 ret = -1;
671 goto end;
672 }
673 if (cmsg->cmsg_type == SCM_RIGHTS) {
674 /*
675 * We found the controle message for file descriptors,
676 * now copy the fds to the fds ptr and return success.
677 */
678 if (cmsg->cmsg_len != CMSG_LEN(sizeof_fds)) {
679 fprintf(stderr, "Error: Received %zu bytes of"
680 "ancillary data for FDs, expected %zu\n",
681 (size_t) cmsg->cmsg_len,
682 (size_t) CMSG_LEN(sizeof_fds));
683 ret = -1;
684 goto end;
685 }
686 memcpy(fds, CMSG_DATA(cmsg), sizeof_fds);
687 ret = sizeof_fds;
688 goto end;
689 }
690 #ifdef __linux__
691 if (cmsg->cmsg_type == SCM_CREDENTIALS) {
692 /*
693 * Expect credentials to be sent when expecting fds even
694 * if no credential were include in the send(). The
695 * kernel adds them...
696 */
697 ret = -1;
698 }
699 #endif /* __linux__ */
700 }
701 end:
702 return ret;
703 }
704
705 static
706 void close_raw_fd(void *ptr)
707 {
708 const int raw_fd = *((const int *) ptr);
709
710 if (raw_fd >= 0) {
711 const int ret = close(raw_fd);
712
713 if (ret) {
714 PERROR("Failed to close file descriptor %d", raw_fd);
715 }
716 }
717 }
718
719 static
720 enum lttng_error_code add_fds_to_payload(struct lttng_dynamic_array *raw_fds,
721 struct lttng_payload *payload)
722 {
723 int i;
724 enum lttng_error_code ret_code = LTTNG_OK;
725 const int fd_count = lttng_dynamic_array_get_count(raw_fds);
726
727 for (i = 0; i < fd_count; i++) {
728 int ret;
729 struct fd_handle *handle;
730 int *raw_fd = (int *) lttng_dynamic_array_get_element(
731 raw_fds, i);
732
733 handle = fd_handle_create(*raw_fd);
734 if (!handle) {
735 ret_code = LTTNG_ERR_NOMEM;
736 goto end;
737 }
738
739 /* FD ownership transferred to the handle. */
740 *raw_fd = -1;
741
742 ret = lttng_payload_push_fd_handle(payload, handle);
743 fd_handle_put(handle);
744 if (ret) {
745 ret_code = LTTNG_ERR_NOMEM;
746 goto end;
747 }
748 }
749
750 end:
751 return ret_code;
752 }
753
754 static
755 ssize_t _lttcomm_recv_payload_fds_unix_sock(int sock, size_t nb_fd,
756 struct lttng_payload *payload, bool blocking)
757 {
758 enum lttng_error_code add_ret;
759 ssize_t ret;
760 struct lttng_dynamic_array raw_fds;
761
762 lttng_dynamic_array_init(&raw_fds, sizeof(int), close_raw_fd);
763 ret = lttng_dynamic_array_set_count(&raw_fds, nb_fd);
764 if (ret) {
765 ret = -LTTNG_ERR_NOMEM;
766 goto end;
767 }
768
769 if (blocking) {
770 ret = lttcomm_recv_fds_unix_sock(
771 sock, (int *) raw_fds.buffer.data, nb_fd);
772 } else {
773 ret = lttcomm_recv_fds_unix_sock_non_block(
774 sock, (int *) raw_fds.buffer.data, nb_fd);
775 }
776
777 if (ret < 0) {
778 goto end;
779 }
780
781 add_ret = add_fds_to_payload(&raw_fds, payload);
782 if (add_ret != LTTNG_OK) {
783 ret = - (int) add_ret;
784 goto end;
785 }
786
787 end:
788 lttng_dynamic_array_reset(&raw_fds);
789 return ret;
790 }
791
792 LTTNG_HIDDEN
793 ssize_t lttcomm_recv_payload_fds_unix_sock(int sock, size_t nb_fd,
794 struct lttng_payload *payload)
795 {
796 return _lttcomm_recv_payload_fds_unix_sock(sock, nb_fd, payload, true);
797 }
798
799 LTTNG_HIDDEN
800 ssize_t lttcomm_recv_payload_fds_unix_sock_non_block(int sock, size_t nb_fd,
801 struct lttng_payload *payload)
802 {
803 return _lttcomm_recv_payload_fds_unix_sock(sock, nb_fd, payload, false);
804 }
805
806 /*
807 * Recv a message accompanied by fd(s) from a non-blocking unix socket.
808 * Only use with non-blocking sockets.
809 *
810 * Returns the size of received data, or negative error value.
811 *
812 * Expect at most "nb_fd" file descriptors.
813 *
814 * Note that based on our comprehension, partial reception of fds is not
815 * possible since the FDs are actually in the control message. It is all or
816 * nothing, still the sender side can send the wrong number of fds.
817 */
818 LTTNG_HIDDEN
819 ssize_t lttcomm_recv_fds_unix_sock_non_block(int sock, int *fds, size_t nb_fd)
820 {
821 struct iovec iov[1];
822 ssize_t ret = 0;
823 struct cmsghdr *cmsg;
824 size_t sizeof_fds = nb_fd * sizeof(int);
825
826 #ifdef __linux__
827 /* Account for the struct ucred cmsg in the buffer size */
828 #define LTTNG_SOCK_RECV_FDS_BUF_SIZE CMSG_SPACE(sizeof_fds) + CMSG_SPACE(sizeof(struct ucred))
829 #else
830 #define LTTNG_SOCK_RECV_FDS_BUF_SIZE CMSG_SPACE(sizeof_fds)
831 #endif /* __linux__ */
832
833 char recv_buf[LTTNG_SOCK_RECV_FDS_BUF_SIZE];
834 struct msghdr msg;
835 char dummy;
836
837 memset(&msg, 0, sizeof(msg));
838
839 /* Prepare to receive the structures */
840 iov[0].iov_base = &dummy;
841 iov[0].iov_len = 1;
842 msg.msg_iov = iov;
843 msg.msg_iovlen = 1;
844
845 cmsg = (struct cmsghdr *) recv_buf;
846 cmsg->cmsg_len = CMSG_LEN(sizeof_fds);
847 cmsg->cmsg_level = SOL_SOCKET;
848 cmsg->cmsg_type = SCM_RIGHTS;
849
850 msg.msg_control = cmsg;
851 msg.msg_controllen = CMSG_LEN(sizeof(recv_buf));
852 msg.msg_flags = 0;
853
854 retry:
855 ret = lttng_recvmsg_nosigpipe(sock, &msg);
856 if (ret < 0) {
857 if (errno == EINTR) {
858 goto retry;
859 } else {
860 /*
861 * We consider EPIPE and EAGAIN/EWOULDBLOCK as expected.
862 */
863 if (errno == EAGAIN || errno == EWOULDBLOCK) {
864 /*
865 * This can happen in non blocking mode.
866 * Nothing was recv.
867 */
868 ret = 0;
869 goto end;
870 }
871
872 if (errno == EPIPE) {
873 /* Expected error, pass error to caller */
874 DBG3("EPIPE on recvmsg");
875 ret = -1;
876 goto end;
877 }
878
879 /* Unexpected error */
880 PERROR("recvmsg");
881 ret = -1;
882 goto end;
883 }
884 }
885
886 if (ret != 1) {
887 fprintf(stderr, "Error: Received %zd bytes, expected %d\n",
888 ret, 1);
889 goto end;
890 }
891
892 if (msg.msg_flags & MSG_CTRUNC) {
893 fprintf(stderr, "Error: Control message truncated.\n");
894 ret = -1;
895 goto end;
896 }
897
898 /*
899 * If the socket was configured with SO_PASSCRED, the kernel will add a
900 * control message (cmsg) to the ancillary data of the unix socket. We
901 * need to expect a cmsg of the SCM_CREDENTIALS as the first control
902 * message.
903 */
904 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
905 if (cmsg->cmsg_level != SOL_SOCKET) {
906 fprintf(stderr, "Error: The socket needs to be of type SOL_SOCKET\n");
907 ret = -1;
908 goto end;
909 }
910 if (cmsg->cmsg_type == SCM_RIGHTS) {
911 /*
912 * We found the controle message for file descriptors,
913 * now copy the fds to the fds ptr and return success.
914 */
915 if (cmsg->cmsg_len != CMSG_LEN(sizeof_fds)) {
916 fprintf(stderr, "Error: Received %zu bytes of"
917 "ancillary data for FDs, expected %zu\n",
918 (size_t) cmsg->cmsg_len,
919 (size_t) CMSG_LEN(sizeof_fds));
920 ret = -1;
921 goto end;
922 }
923 memcpy(fds, CMSG_DATA(cmsg), sizeof_fds);
924 ret = sizeof_fds;
925 goto end;
926 }
927 #ifdef __linux__
928 if (cmsg->cmsg_type == SCM_CREDENTIALS) {
929 /*
930 * Expect credentials to be sent when expecting fds even
931 * if no credential were include in the send(). The
932 * kernel adds them...
933 */
934 ret = -1;
935 }
936 #endif /* __linux__ */
937 }
938 end:
939 return ret;
940 }
941
942 /*
943 * Send a message with credentials over a unix socket.
944 *
945 * Returns the size of data sent, or negative error value.
946 */
947 LTTNG_HIDDEN
948 ssize_t lttcomm_send_creds_unix_sock(int sock, const void *buf, size_t len)
949 {
950 struct msghdr msg;
951 struct iovec iov[1];
952 ssize_t ret = -1;
953 #ifdef __linux__
954 struct cmsghdr *cmptr;
955 size_t sizeof_cred = sizeof(lttng_sock_cred);
956 char anc_buf[CMSG_SPACE(sizeof_cred)];
957 lttng_sock_cred *creds;
958
959 memset(anc_buf, 0, CMSG_SPACE(sizeof_cred) * sizeof(char));
960 #endif /* __linux__ */
961
962 memset(&msg, 0, sizeof(msg));
963
964 iov[0].iov_base = (void *) buf;
965 iov[0].iov_len = len;
966 msg.msg_iov = iov;
967 msg.msg_iovlen = 1;
968
969 #ifdef __linux__
970 msg.msg_control = (caddr_t) anc_buf;
971 msg.msg_controllen = CMSG_LEN(sizeof_cred);
972
973 cmptr = CMSG_FIRSTHDR(&msg);
974 if (!cmptr) {
975 return -1;
976 }
977 cmptr->cmsg_level = SOL_SOCKET;
978 cmptr->cmsg_type = LTTNG_SOCK_CREDS;
979 cmptr->cmsg_len = CMSG_LEN(sizeof_cred);
980
981 creds = (lttng_sock_cred*) CMSG_DATA(cmptr);
982
983 LTTNG_SOCK_SET_UID_CRED(creds, geteuid());
984 LTTNG_SOCK_SET_GID_CRED(creds, getegid());
985 LTTNG_SOCK_SET_PID_CRED(creds, getpid());
986 #endif /* __linux__ */
987
988 do {
989 ret = sendmsg(sock, &msg, 0);
990 } while (ret < 0 && errno == EINTR);
991 if (ret < 0) {
992 /*
993 * Only warn about EPIPE when quiet mode is deactivated.
994 * We consider EPIPE as expected.
995 */
996 if (errno != EPIPE || !lttng_opt_quiet) {
997 PERROR("sendmsg");
998 }
999 }
1000 return ret;
1001 }
1002
1003 /*
1004 * Recv a message accompanied with credentials from a unix socket.
1005 *
1006 * Returns the size of received data, or negative error value.
1007 */
1008 LTTNG_HIDDEN
1009 ssize_t lttcomm_recv_creds_unix_sock(int sock, void *buf, size_t len,
1010 lttng_sock_cred *creds)
1011 {
1012 struct msghdr msg;
1013 struct iovec iov[1];
1014 ssize_t ret;
1015 size_t len_last;
1016 #ifdef __linux__
1017 struct cmsghdr *cmptr;
1018 size_t sizeof_cred = sizeof(lttng_sock_cred);
1019 char anc_buf[CMSG_SPACE(sizeof_cred)];
1020 #endif /* __linux__ */
1021
1022 memset(&msg, 0, sizeof(msg));
1023
1024 /* Not allowed */
1025 if (creds == NULL) {
1026 ret = -1;
1027 goto end;
1028 }
1029
1030 /* Prepare to receive the structures */
1031 iov[0].iov_base = buf;
1032 iov[0].iov_len = len;
1033 msg.msg_iov = iov;
1034 msg.msg_iovlen = 1;
1035
1036 #ifdef __linux__
1037 msg.msg_control = anc_buf;
1038 msg.msg_controllen = sizeof(anc_buf);
1039 #endif /* __linux__ */
1040
1041 do {
1042 len_last = iov[0].iov_len;
1043 ret = recvmsg(sock, &msg, 0);
1044 if (ret > 0) {
1045 iov[0].iov_base += ret;
1046 iov[0].iov_len -= ret;
1047 assert(ret <= len_last);
1048 }
1049 } while ((ret > 0 && ret < len_last) || (ret < 0 && errno == EINTR));
1050 if (ret < 0) {
1051 PERROR("recvmsg fds");
1052 goto end;
1053 } else if (ret > 0) {
1054 ret = len;
1055 }
1056 /* Else ret = 0 meaning an orderly shutdown. */
1057
1058 #ifdef __linux__
1059 if (msg.msg_flags & MSG_CTRUNC) {
1060 fprintf(stderr, "Error: Control message truncated.\n");
1061 ret = -1;
1062 goto end;
1063 }
1064
1065 cmptr = CMSG_FIRSTHDR(&msg);
1066 if (cmptr == NULL) {
1067 fprintf(stderr, "Error: Invalid control message header\n");
1068 ret = -1;
1069 goto end;
1070 }
1071
1072 if (cmptr->cmsg_level != SOL_SOCKET ||
1073 cmptr->cmsg_type != LTTNG_SOCK_CREDS) {
1074 fprintf(stderr, "Didn't received any credentials\n");
1075 ret = -1;
1076 goto end;
1077 }
1078
1079 if (cmptr->cmsg_len != CMSG_LEN(sizeof_cred)) {
1080 fprintf(stderr, "Error: Received %zu bytes of ancillary data, expected %zu\n",
1081 (size_t) cmptr->cmsg_len, (size_t) CMSG_LEN(sizeof_cred));
1082 ret = -1;
1083 goto end;
1084 }
1085
1086 memcpy(creds, CMSG_DATA(cmptr), sizeof_cred);
1087 #elif (defined(__FreeBSD__) || defined(__CYGWIN__) || defined(__sun__) || defined(__APPLE__))
1088 {
1089 int peer_ret;
1090
1091 peer_ret = getpeereid(sock, &creds->uid, &creds->gid);
1092 if (peer_ret != 0) {
1093 return peer_ret;
1094 }
1095 }
1096 #else
1097 #error "Please implement credential support for your OS."
1098 #endif /* __linux__ */
1099
1100 end:
1101 return ret;
1102 }
1103
1104 /*
1105 * Set socket option to use credentials passing.
1106 */
1107 #ifdef __linux__
1108 LTTNG_HIDDEN
1109 int lttcomm_setsockopt_creds_unix_sock(int sock)
1110 {
1111 int ret, on = 1;
1112
1113 /* Set socket for credentials retrieval */
1114 ret = setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
1115 if (ret < 0) {
1116 PERROR("setsockopt creds unix sock");
1117 }
1118 return ret;
1119 }
1120 #elif (defined(__FreeBSD__) || defined(__CYGWIN__) || defined(__sun__) || defined(__APPLE__))
1121 LTTNG_HIDDEN
1122 int lttcomm_setsockopt_creds_unix_sock(int sock)
1123 {
1124 return 0;
1125 }
1126 #else
1127 #error "Please implement credential support for your OS."
1128 #endif /* __linux__ */
This page took 0.086217 seconds and 4 git commands to generate.