payload: use fd_handle instead of raw file descriptors
[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 /*
457 * Prepare a contiguous array of file descriptors to send them.
458 *
459 * Note that the reference to each fd is released during the iteration;
460 * we're just getting the numerical value of the fds to conform to the
461 * syscall's interface. We rely on the fact that "view" must remain
462 * valid for the duration of the call and that the underlying payload
463 * owns a reference to the fd_handles.
464 */
465 for (i = 0; i < fd_count; i++) {
466 struct fd_handle *handle =
467 lttng_payload_view_pop_fd_handle(view);
468 const int raw_fd = fd_handle_get_fd(handle);
469 const int add_ret = lttng_dynamic_array_add_element(
470 &raw_fds, &raw_fd);
471
472 fd_handle_put(handle);
473 if (add_ret) {
474 ret = -LTTNG_ERR_NOMEM;
475 goto end;
476 }
477 }
478
479 if (blocking) {
480 ret = lttcomm_send_fds_unix_sock(sock,
481 (const int *) raw_fds.buffer.data, fd_count);
482 } else {
483 ret = lttcomm_send_fds_unix_sock_non_block(sock,
484 (const int *) raw_fds.buffer.data, fd_count);
485 }
486
487 end:
488 lttng_dynamic_array_reset(&raw_fds);
489 return ret;
490 }
491
492 LTTNG_HIDDEN
493 ssize_t lttcomm_send_payload_view_fds_unix_sock(int sock,
494 struct lttng_payload_view *view)
495 {
496 return _lttcomm_send_payload_view_fds_unix_sock(sock, view, true);
497 }
498
499 LTTNG_HIDDEN
500 ssize_t lttcomm_send_payload_view_fds_unix_sock_non_block(int sock,
501 struct lttng_payload_view *view)
502 {
503 return _lttcomm_send_payload_view_fds_unix_sock(sock, view, false);
504 }
505
506 /*
507 * Send a message accompanied by fd(s) over a unix socket.
508 * Only use for non blocking socket.
509 *
510 * Returns the size of data sent, or negative error value.
511 */
512 LTTNG_HIDDEN
513 ssize_t lttcomm_send_fds_unix_sock_non_block(int sock, const int *fds, size_t nb_fd)
514 {
515 struct msghdr msg;
516 struct cmsghdr *cmptr;
517 struct iovec iov[1];
518 ssize_t ret = -1;
519 unsigned int sizeof_fds = nb_fd * sizeof(int);
520 char tmp[CMSG_SPACE(sizeof_fds)];
521 char dummy = 0;
522
523 memset(&msg, 0, sizeof(msg));
524 memset(tmp, 0, sizeof(tmp));
525
526 if (nb_fd > LTTCOMM_MAX_SEND_FDS)
527 return -EINVAL;
528
529 msg.msg_control = (caddr_t)tmp;
530 msg.msg_controllen = CMSG_LEN(sizeof_fds);
531
532 cmptr = CMSG_FIRSTHDR(&msg);
533 if (!cmptr) {
534 return -1;
535 }
536
537 cmptr->cmsg_level = SOL_SOCKET;
538 cmptr->cmsg_type = SCM_RIGHTS;
539 cmptr->cmsg_len = CMSG_LEN(sizeof_fds);
540 memcpy(CMSG_DATA(cmptr), fds, sizeof_fds);
541 /* Sum of the length of all control messages in the buffer: */
542 msg.msg_controllen = cmptr->cmsg_len;
543
544 iov[0].iov_base = &dummy;
545 iov[0].iov_len = 1;
546 msg.msg_iov = iov;
547 msg.msg_iovlen = 1;
548
549 retry:
550 ret = sendmsg(sock, &msg, 0);
551 if (ret < 0) {
552 if (errno == EINTR) {
553 goto retry;
554 } else {
555 /*
556 * We consider EPIPE and EAGAIN/EWOULDBLOCK as expected.
557 */
558 if (errno == EAGAIN || errno == EWOULDBLOCK) {
559 /*
560 * This can happen in non blocking mode.
561 * Nothing was sent.
562 */
563 ret = 0;
564 goto end;
565 }
566
567 if (errno == EPIPE) {
568 /* Expected error, pass error to caller */
569 DBG3("EPIPE on sendmsg");
570 ret = -1;
571 goto end;
572 }
573
574 /* Unexpected error */
575 PERROR("sendmsg");
576 ret = -1;
577 goto end;
578 }
579 }
580
581 end:
582 return ret;
583 }
584
585 /*
586 * Recv a message accompanied by fd(s) from a unix socket.
587 *
588 * Returns the size of received data, or negative error value.
589 *
590 * Expect at most "nb_fd" file descriptors. Returns the number of fd
591 * actually received in nb_fd.
592 */
593 LTTNG_HIDDEN
594 ssize_t lttcomm_recv_fds_unix_sock(int sock, int *fds, size_t nb_fd)
595 {
596 struct iovec iov[1];
597 ssize_t ret = 0;
598 struct cmsghdr *cmsg;
599 size_t sizeof_fds = nb_fd * sizeof(int);
600
601 #ifdef __linux__
602 /* Account for the struct ucred cmsg in the buffer size */
603 #define LTTNG_SOCK_RECV_FDS_BUF_SIZE CMSG_SPACE(sizeof_fds) + CMSG_SPACE(sizeof(struct ucred))
604 #else
605 #define LTTNG_SOCK_RECV_FDS_BUF_SIZE CMSG_SPACE(sizeof_fds)
606 #endif /* __linux__ */
607
608 char recv_buf[LTTNG_SOCK_RECV_FDS_BUF_SIZE];
609 struct msghdr msg;
610 char dummy;
611
612 memset(&msg, 0, sizeof(msg));
613
614 /* Prepare to receive the structures */
615 iov[0].iov_base = &dummy;
616 iov[0].iov_len = 1;
617 msg.msg_iov = iov;
618 msg.msg_iovlen = 1;
619
620 cmsg = (struct cmsghdr *) recv_buf;
621 cmsg->cmsg_len = CMSG_LEN(sizeof_fds);
622 cmsg->cmsg_level = SOL_SOCKET;
623 cmsg->cmsg_type = SCM_RIGHTS;
624
625 msg.msg_control = cmsg;
626 msg.msg_controllen = CMSG_LEN(sizeof(recv_buf));
627 msg.msg_flags = 0;
628
629 retry:
630 ret = lttng_recvmsg_nosigpipe(sock, &msg);
631 if (ret < 0) {
632 if (errno == EINTR) {
633 goto retry;
634 } else {
635 /* We consider EPIPE and EAGAIN as expected. */
636 if (!lttng_opt_quiet &&
637 (errno != EPIPE && errno != EAGAIN)) {
638 PERROR("recvmsg");
639 }
640 goto end;
641 }
642 }
643
644 if (ret != 1) {
645 fprintf(stderr, "Error: Received %zd bytes, expected %d\n",
646 ret, 1);
647 goto end;
648 }
649
650 if (msg.msg_flags & MSG_CTRUNC) {
651 fprintf(stderr, "Error: Control message truncated.\n");
652 ret = -1;
653 goto end;
654 }
655
656 /*
657 * If the socket was configured with SO_PASSCRED, the kernel will add a
658 * control message (cmsg) to the ancillary data of the unix socket. We
659 * need to expect a cmsg of the SCM_CREDENTIALS as the first control
660 * message.
661 */
662 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
663 if (cmsg->cmsg_level != SOL_SOCKET) {
664 fprintf(stderr, "Error: The socket needs to be of type SOL_SOCKET\n");
665 ret = -1;
666 goto end;
667 }
668 if (cmsg->cmsg_type == SCM_RIGHTS) {
669 /*
670 * We found the controle message for file descriptors,
671 * now copy the fds to the fds ptr and return success.
672 */
673 if (cmsg->cmsg_len != CMSG_LEN(sizeof_fds)) {
674 fprintf(stderr, "Error: Received %zu bytes of"
675 "ancillary data for FDs, expected %zu\n",
676 (size_t) cmsg->cmsg_len,
677 (size_t) CMSG_LEN(sizeof_fds));
678 ret = -1;
679 goto end;
680 }
681 memcpy(fds, CMSG_DATA(cmsg), sizeof_fds);
682 ret = sizeof_fds;
683 goto end;
684 }
685 #ifdef __linux__
686 if (cmsg->cmsg_type == SCM_CREDENTIALS) {
687 /*
688 * Expect credentials to be sent when expecting fds even
689 * if no credential were include in the send(). The
690 * kernel adds them...
691 */
692 ret = -1;
693 }
694 #endif /* __linux__ */
695 }
696 end:
697 return ret;
698 }
699
700 static
701 void close_raw_fd(void *ptr)
702 {
703 const int raw_fd = *((const int *) ptr);
704
705 if (raw_fd >= 0) {
706 const int ret = close(raw_fd);
707
708 if (ret) {
709 PERROR("Failed to close file descriptor %d", raw_fd);
710 }
711 }
712 }
713
714 static
715 enum lttng_error_code add_fds_to_payload(struct lttng_dynamic_array *raw_fds,
716 struct lttng_payload *payload)
717 {
718 int i;
719 enum lttng_error_code ret_code = LTTNG_OK;
720 const int fd_count = lttng_dynamic_array_get_count(raw_fds);
721
722 for (i = 0; i < fd_count; i++) {
723 int ret;
724 struct fd_handle *handle;
725 int *raw_fd = (int *) lttng_dynamic_array_get_element(
726 raw_fds, i);
727
728 handle = fd_handle_create(*raw_fd);
729 if (!handle) {
730 ret_code = LTTNG_ERR_NOMEM;
731 goto end;
732 }
733
734 /* FD ownership transferred to the handle. */
735 *raw_fd = -1;
736
737 ret = lttng_payload_push_fd_handle(payload, handle);
738 fd_handle_put(handle);
739 if (ret) {
740 ret_code = LTTNG_ERR_NOMEM;
741 goto end;
742 }
743 }
744
745 end:
746 return ret_code;
747 }
748
749 static
750 ssize_t _lttcomm_recv_payload_fds_unix_sock(int sock, size_t nb_fd,
751 struct lttng_payload *payload, bool blocking)
752 {
753 enum lttng_error_code add_ret;
754 ssize_t ret;
755 struct lttng_dynamic_array raw_fds;
756
757 lttng_dynamic_array_init(&raw_fds, sizeof(int), close_raw_fd);
758 ret = lttng_dynamic_array_set_count(&raw_fds, nb_fd);
759 if (ret) {
760 ret = -LTTNG_ERR_NOMEM;
761 goto end;
762 }
763
764 if (blocking) {
765 ret = lttcomm_recv_fds_unix_sock(
766 sock, (int *) raw_fds.buffer.data, nb_fd);
767 } else {
768 ret = lttcomm_recv_fds_unix_sock_non_block(
769 sock, (int *) raw_fds.buffer.data, nb_fd);
770 }
771
772 if (ret < 0) {
773 goto end;
774 }
775
776 add_ret = add_fds_to_payload(&raw_fds, payload);
777 if (add_ret != LTTNG_OK) {
778 ret = - (int) add_ret;
779 goto end;
780 }
781
782 end:
783 lttng_dynamic_array_reset(&raw_fds);
784 return ret;
785 }
786
787 LTTNG_HIDDEN
788 ssize_t lttcomm_recv_payload_fds_unix_sock(int sock, size_t nb_fd,
789 struct lttng_payload *payload)
790 {
791 return _lttcomm_recv_payload_fds_unix_sock(sock, nb_fd, payload, true);
792 }
793
794 LTTNG_HIDDEN
795 ssize_t lttcomm_recv_payload_fds_unix_sock_non_block(int sock, size_t nb_fd,
796 struct lttng_payload *payload)
797 {
798 return _lttcomm_recv_payload_fds_unix_sock(sock, nb_fd, payload, false);
799 }
800
801 /*
802 * Recv a message accompanied by fd(s) from a non-blocking unix socket.
803 * Only use with non-blocking sockets.
804 *
805 * Returns the size of received data, or negative error value.
806 *
807 * Expect at most "nb_fd" file descriptors.
808 *
809 * Note that based on our comprehension, partial reception of fds is not
810 * possible since the FDs are actually in the control message. It is all or
811 * nothing, still the sender side can send the wrong number of fds.
812 */
813 LTTNG_HIDDEN
814 ssize_t lttcomm_recv_fds_unix_sock_non_block(int sock, int *fds, size_t nb_fd)
815 {
816 struct iovec iov[1];
817 ssize_t ret = 0;
818 struct cmsghdr *cmsg;
819 size_t sizeof_fds = nb_fd * sizeof(int);
820
821 #ifdef __linux__
822 /* Account for the struct ucred cmsg in the buffer size */
823 #define LTTNG_SOCK_RECV_FDS_BUF_SIZE CMSG_SPACE(sizeof_fds) + CMSG_SPACE(sizeof(struct ucred))
824 #else
825 #define LTTNG_SOCK_RECV_FDS_BUF_SIZE CMSG_SPACE(sizeof_fds)
826 #endif /* __linux__ */
827
828 char recv_buf[LTTNG_SOCK_RECV_FDS_BUF_SIZE];
829 struct msghdr msg;
830 char dummy;
831
832 memset(&msg, 0, sizeof(msg));
833
834 /* Prepare to receive the structures */
835 iov[0].iov_base = &dummy;
836 iov[0].iov_len = 1;
837 msg.msg_iov = iov;
838 msg.msg_iovlen = 1;
839
840 cmsg = (struct cmsghdr *) recv_buf;
841 cmsg->cmsg_len = CMSG_LEN(sizeof_fds);
842 cmsg->cmsg_level = SOL_SOCKET;
843 cmsg->cmsg_type = SCM_RIGHTS;
844
845 msg.msg_control = cmsg;
846 msg.msg_controllen = CMSG_LEN(sizeof(recv_buf));
847 msg.msg_flags = 0;
848
849 retry:
850 ret = lttng_recvmsg_nosigpipe(sock, &msg);
851 if (ret < 0) {
852 if (errno == EINTR) {
853 goto retry;
854 } else {
855 /*
856 * We consider EPIPE and EAGAIN/EWOULDBLOCK as expected.
857 */
858 if (errno == EAGAIN || errno == EWOULDBLOCK) {
859 /*
860 * This can happen in non blocking mode.
861 * Nothing was recv.
862 */
863 ret = 0;
864 goto end;
865 }
866
867 if (errno == EPIPE) {
868 /* Expected error, pass error to caller */
869 DBG3("EPIPE on recvmsg");
870 ret = -1;
871 goto end;
872 }
873
874 /* Unexpected error */
875 PERROR("recvmsg");
876 ret = -1;
877 goto end;
878 }
879 }
880
881 if (ret != 1) {
882 fprintf(stderr, "Error: Received %zd bytes, expected %d\n",
883 ret, 1);
884 goto end;
885 }
886
887 if (msg.msg_flags & MSG_CTRUNC) {
888 fprintf(stderr, "Error: Control message truncated.\n");
889 ret = -1;
890 goto end;
891 }
892
893 /*
894 * If the socket was configured with SO_PASSCRED, the kernel will add a
895 * control message (cmsg) to the ancillary data of the unix socket. We
896 * need to expect a cmsg of the SCM_CREDENTIALS as the first control
897 * message.
898 */
899 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
900 if (cmsg->cmsg_level != SOL_SOCKET) {
901 fprintf(stderr, "Error: The socket needs to be of type SOL_SOCKET\n");
902 ret = -1;
903 goto end;
904 }
905 if (cmsg->cmsg_type == SCM_RIGHTS) {
906 /*
907 * We found the controle message for file descriptors,
908 * now copy the fds to the fds ptr and return success.
909 */
910 if (cmsg->cmsg_len != CMSG_LEN(sizeof_fds)) {
911 fprintf(stderr, "Error: Received %zu bytes of"
912 "ancillary data for FDs, expected %zu\n",
913 (size_t) cmsg->cmsg_len,
914 (size_t) CMSG_LEN(sizeof_fds));
915 ret = -1;
916 goto end;
917 }
918 memcpy(fds, CMSG_DATA(cmsg), sizeof_fds);
919 ret = sizeof_fds;
920 goto end;
921 }
922 #ifdef __linux__
923 if (cmsg->cmsg_type == SCM_CREDENTIALS) {
924 /*
925 * Expect credentials to be sent when expecting fds even
926 * if no credential were include in the send(). The
927 * kernel adds them...
928 */
929 ret = -1;
930 }
931 #endif /* __linux__ */
932 }
933 end:
934 return ret;
935 }
936
937 /*
938 * Send a message with credentials over a unix socket.
939 *
940 * Returns the size of data sent, or negative error value.
941 */
942 LTTNG_HIDDEN
943 ssize_t lttcomm_send_creds_unix_sock(int sock, const void *buf, size_t len)
944 {
945 struct msghdr msg;
946 struct iovec iov[1];
947 ssize_t ret = -1;
948 #ifdef __linux__
949 struct cmsghdr *cmptr;
950 size_t sizeof_cred = sizeof(lttng_sock_cred);
951 char anc_buf[CMSG_SPACE(sizeof_cred)];
952 lttng_sock_cred *creds;
953
954 memset(anc_buf, 0, CMSG_SPACE(sizeof_cred) * sizeof(char));
955 #endif /* __linux__ */
956
957 memset(&msg, 0, sizeof(msg));
958
959 iov[0].iov_base = (void *) buf;
960 iov[0].iov_len = len;
961 msg.msg_iov = iov;
962 msg.msg_iovlen = 1;
963
964 #ifdef __linux__
965 msg.msg_control = (caddr_t) anc_buf;
966 msg.msg_controllen = CMSG_LEN(sizeof_cred);
967
968 cmptr = CMSG_FIRSTHDR(&msg);
969 if (!cmptr) {
970 return -1;
971 }
972 cmptr->cmsg_level = SOL_SOCKET;
973 cmptr->cmsg_type = LTTNG_SOCK_CREDS;
974 cmptr->cmsg_len = CMSG_LEN(sizeof_cred);
975
976 creds = (lttng_sock_cred*) CMSG_DATA(cmptr);
977
978 LTTNG_SOCK_SET_UID_CRED(creds, geteuid());
979 LTTNG_SOCK_SET_GID_CRED(creds, getegid());
980 LTTNG_SOCK_SET_PID_CRED(creds, getpid());
981 #endif /* __linux__ */
982
983 do {
984 ret = sendmsg(sock, &msg, 0);
985 } while (ret < 0 && errno == EINTR);
986 if (ret < 0) {
987 /*
988 * Only warn about EPIPE when quiet mode is deactivated.
989 * We consider EPIPE as expected.
990 */
991 if (errno != EPIPE || !lttng_opt_quiet) {
992 PERROR("sendmsg");
993 }
994 }
995 return ret;
996 }
997
998 /*
999 * Recv a message accompanied with credentials from a unix socket.
1000 *
1001 * Returns the size of received data, or negative error value.
1002 */
1003 LTTNG_HIDDEN
1004 ssize_t lttcomm_recv_creds_unix_sock(int sock, void *buf, size_t len,
1005 lttng_sock_cred *creds)
1006 {
1007 struct msghdr msg;
1008 struct iovec iov[1];
1009 ssize_t ret;
1010 size_t len_last;
1011 #ifdef __linux__
1012 struct cmsghdr *cmptr;
1013 size_t sizeof_cred = sizeof(lttng_sock_cred);
1014 char anc_buf[CMSG_SPACE(sizeof_cred)];
1015 #endif /* __linux__ */
1016
1017 memset(&msg, 0, sizeof(msg));
1018
1019 /* Not allowed */
1020 if (creds == NULL) {
1021 ret = -1;
1022 goto end;
1023 }
1024
1025 /* Prepare to receive the structures */
1026 iov[0].iov_base = buf;
1027 iov[0].iov_len = len;
1028 msg.msg_iov = iov;
1029 msg.msg_iovlen = 1;
1030
1031 #ifdef __linux__
1032 msg.msg_control = anc_buf;
1033 msg.msg_controllen = sizeof(anc_buf);
1034 #endif /* __linux__ */
1035
1036 do {
1037 len_last = iov[0].iov_len;
1038 ret = recvmsg(sock, &msg, 0);
1039 if (ret > 0) {
1040 iov[0].iov_base += ret;
1041 iov[0].iov_len -= ret;
1042 assert(ret <= len_last);
1043 }
1044 } while ((ret > 0 && ret < len_last) || (ret < 0 && errno == EINTR));
1045 if (ret < 0) {
1046 PERROR("recvmsg fds");
1047 goto end;
1048 } else if (ret > 0) {
1049 ret = len;
1050 }
1051 /* Else ret = 0 meaning an orderly shutdown. */
1052
1053 #ifdef __linux__
1054 if (msg.msg_flags & MSG_CTRUNC) {
1055 fprintf(stderr, "Error: Control message truncated.\n");
1056 ret = -1;
1057 goto end;
1058 }
1059
1060 cmptr = CMSG_FIRSTHDR(&msg);
1061 if (cmptr == NULL) {
1062 fprintf(stderr, "Error: Invalid control message header\n");
1063 ret = -1;
1064 goto end;
1065 }
1066
1067 if (cmptr->cmsg_level != SOL_SOCKET ||
1068 cmptr->cmsg_type != LTTNG_SOCK_CREDS) {
1069 fprintf(stderr, "Didn't received any credentials\n");
1070 ret = -1;
1071 goto end;
1072 }
1073
1074 if (cmptr->cmsg_len != CMSG_LEN(sizeof_cred)) {
1075 fprintf(stderr, "Error: Received %zu bytes of ancillary data, expected %zu\n",
1076 (size_t) cmptr->cmsg_len, (size_t) CMSG_LEN(sizeof_cred));
1077 ret = -1;
1078 goto end;
1079 }
1080
1081 memcpy(creds, CMSG_DATA(cmptr), sizeof_cred);
1082 #elif (defined(__FreeBSD__) || defined(__CYGWIN__) || defined(__sun__) || defined(__APPLE__))
1083 {
1084 int peer_ret;
1085
1086 peer_ret = getpeereid(sock, &creds->uid, &creds->gid);
1087 if (peer_ret != 0) {
1088 return peer_ret;
1089 }
1090 }
1091 #else
1092 #error "Please implement credential support for your OS."
1093 #endif /* __linux__ */
1094
1095 end:
1096 return ret;
1097 }
1098
1099 /*
1100 * Set socket option to use credentials passing.
1101 */
1102 #ifdef __linux__
1103 LTTNG_HIDDEN
1104 int lttcomm_setsockopt_creds_unix_sock(int sock)
1105 {
1106 int ret, on = 1;
1107
1108 /* Set socket for credentials retrieval */
1109 ret = setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
1110 if (ret < 0) {
1111 PERROR("setsockopt creds unix sock");
1112 }
1113 return ret;
1114 }
1115 #elif (defined(__FreeBSD__) || defined(__CYGWIN__) || defined(__sun__) || defined(__APPLE__))
1116 LTTNG_HIDDEN
1117 int lttcomm_setsockopt_creds_unix_sock(int sock)
1118 {
1119 return 0;
1120 }
1121 #else
1122 #error "Please implement credential support for your OS."
1123 #endif /* __linux__ */
This page took 0.056348 seconds and 4 git commands to generate.