d727cf4179380b094e98259f4dfa477bf41038f8
[lttng-tools.git] / src / common / runas.c
1 /*
2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
3 * Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License, version 2 only,
7 * as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #define _LGPL_SOURCE
20 #include <errno.h>
21 #include <limits.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/wait.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <unistd.h>
29 #include <fcntl.h>
30 #include <sched.h>
31 #include <signal.h>
32 #include <assert.h>
33 #include <signal.h>
34
35 #include <common/lttng-kernel.h>
36 #include <common/common.h>
37 #include <common/utils.h>
38 #include <common/compat/getenv.h>
39 #include <common/compat/prctl.h>
40 #include <common/unix.h>
41 #include <common/defaults.h>
42 #include <common/lttng-elf.h>
43
44 #include <lttng/constant.h>
45
46 #include "runas.h"
47
48 struct run_as_data;
49 struct run_as_ret;
50 typedef int (*run_as_fct)(struct run_as_data *data, struct run_as_ret *ret_value);
51
52 struct run_as_mkdir_data {
53 char path[PATH_MAX];
54 mode_t mode;
55 };
56
57 struct run_as_open_data {
58 char path[PATH_MAX];
59 int flags;
60 mode_t mode;
61 };
62
63 struct run_as_unlink_data {
64 char path[PATH_MAX];
65 };
66
67 struct run_as_rmdir_recursive_data {
68 char path[PATH_MAX];
69 };
70
71 struct run_as_extract_elf_symbol_offset_data {
72 char function[LTTNG_SYMBOL_NAME_LEN];
73 };
74
75 struct run_as_extract_sdt_probe_offsets_data {
76 char probe_name[LTTNG_SYMBOL_NAME_LEN];
77 char provider_name[LTTNG_SYMBOL_NAME_LEN];
78 };
79
80 struct run_as_mkdir_ret {
81 int ret;
82 };
83
84 struct run_as_open_ret {
85 int ret;
86 };
87
88 struct run_as_unlink_ret {
89 int ret;
90 };
91
92 struct run_as_rmdir_recursive_ret {
93 int ret;
94 };
95
96 struct run_as_extract_elf_symbol_offset_ret {
97 uint64_t offset;
98 };
99
100 struct run_as_extract_sdt_probe_offsets_ret {
101 uint32_t num_offset;
102 uint64_t offsets[LTTNG_KERNEL_MAX_UPROBE_NUM];
103 };
104
105 enum run_as_cmd {
106 RUN_AS_MKDIR,
107 RUN_AS_OPEN,
108 RUN_AS_UNLINK,
109 RUN_AS_RMDIR_RECURSIVE,
110 RUN_AS_MKDIR_RECURSIVE,
111 RUN_AS_EXTRACT_ELF_SYMBOL_OFFSET,
112 RUN_AS_EXTRACT_SDT_PROBE_OFFSETS,
113 };
114
115 struct run_as_data {
116 enum run_as_cmd cmd;
117 int fd;
118 union {
119 struct run_as_mkdir_data mkdir;
120 struct run_as_open_data open;
121 struct run_as_unlink_data unlink;
122 struct run_as_rmdir_recursive_data rmdir_recursive;
123 struct run_as_extract_elf_symbol_offset_data extract_elf_symbol_offset;
124 struct run_as_extract_sdt_probe_offsets_data extract_sdt_probe_offsets;
125 } u;
126 uid_t uid;
127 gid_t gid;
128 };
129
130 /*
131 * The run_as_ret structure holds the returned value and status of the command.
132 *
133 * The `u` union field holds the return value of the command; in most cases it
134 * represents the success or the failure of the command. In more complex
135 * commands, it holds a computed value.
136 *
137 * The _errno field is the errno recorded after the execution of the command.
138 *
139 * The _error fields is used the signify that return status of the command. For
140 * simple commands returning `int` the _error field will be the same as the
141 * ret_int field. In complex commands, it signify the success or failure of the
142 * command.
143 *
144 */
145 struct run_as_ret {
146 int fd;
147 union {
148 struct run_as_mkdir_ret mkdir;
149 struct run_as_open_ret open;
150 struct run_as_unlink_ret unlink;
151 struct run_as_rmdir_recursive_ret rmdir_recursive;
152 struct run_as_extract_elf_symbol_offset_ret extract_elf_symbol_offset;
153 struct run_as_extract_sdt_probe_offsets_ret extract_sdt_probe_offsets;
154 } u;
155 int _errno;
156 bool _error;
157 };
158
159 struct run_as_worker {
160 pid_t pid; /* Worker PID. */
161 int sockpair[2];
162 char *procname;
163 };
164
165 /* Single global worker per process (for now). */
166 static struct run_as_worker *global_worker;
167 /* Lock protecting the worker. */
168 static pthread_mutex_t worker_lock = PTHREAD_MUTEX_INITIALIZER;
169
170 #ifdef VALGRIND
171 static
172 int use_clone(void)
173 {
174 return 0;
175 }
176 #else
177 static
178 int use_clone(void)
179 {
180 return !lttng_secure_getenv("LTTNG_DEBUG_NOCLONE");
181 }
182 #endif
183
184 LTTNG_HIDDEN
185 int _utils_mkdir_recursive_unsafe(const char *path, mode_t mode);
186
187 /*
188 * Create recursively directory using the FULL path.
189 */
190 static
191 int _mkdir_recursive(struct run_as_data *data, struct run_as_ret *ret_value)
192 {
193 const char *path;
194 mode_t mode;
195
196 path = data->u.mkdir.path;
197 mode = data->u.mkdir.mode;
198
199 /* Safe to call as we have transitioned to the requested uid/gid. */
200 ret_value->u.mkdir.ret = _utils_mkdir_recursive_unsafe(path, mode);
201 ret_value->_errno = errno;
202 ret_value->_error = (ret_value->u.mkdir.ret) ? true : false;
203 return ret_value->u.mkdir.ret;
204 }
205
206 static
207 int _mkdir(struct run_as_data *data, struct run_as_ret *ret_value)
208 {
209 ret_value->u.mkdir.ret = mkdir(data->u.mkdir.path, data->u.mkdir.mode);
210 ret_value->_errno = errno;
211 ret_value->_error = (ret_value->u.mkdir.ret) ? true : false;
212 return ret_value->u.mkdir.ret;
213 }
214
215 static
216 int _open(struct run_as_data *data, struct run_as_ret *ret_value)
217 {
218 ret_value->u.open.ret = open(data->u.open.path, data->u.open.flags, data->u.open.mode);
219 ret_value->fd = ret_value->u.open.ret;
220 ret_value->_errno = errno;
221 ret_value->_error = ret_value->u.open.ret < 0;
222 return ret_value->u.open.ret;
223 }
224
225 static
226 int _unlink(struct run_as_data *data, struct run_as_ret *ret_value)
227 {
228 ret_value->u.unlink.ret = unlink(data->u.unlink.path);
229 ret_value->_errno = errno;
230 ret_value->_error = (ret_value->u.unlink.ret) ? true : false;
231 return ret_value->u.unlink.ret;
232 }
233
234 static
235 int _rmdir_recursive(struct run_as_data *data, struct run_as_ret *ret_value)
236 {
237 ret_value->u.rmdir_recursive.ret = utils_recursive_rmdir(data->u.rmdir_recursive.path);
238 ret_value->_errno = errno;
239 ret_value->_error = (ret_value->u.rmdir_recursive.ret) ? true : false;
240 return ret_value->u.rmdir_recursive.ret;
241 }
242
243 #ifdef HAVE_ELF_H
244 static
245 int _extract_elf_symbol_offset(struct run_as_data *data,
246 struct run_as_ret *ret_value)
247 {
248 int ret = 0;
249 ret_value->_error = false;
250
251 ret = lttng_elf_get_symbol_offset(data->fd,
252 data->u.extract_elf_symbol_offset.function,
253 &ret_value->u.extract_elf_symbol_offset.offset);
254 if (ret) {
255 DBG("Failed to extract ELF function offset");
256 ret_value->_error = true;
257 }
258
259 return ret;
260 }
261
262 static
263 int _extract_sdt_probe_offsets(struct run_as_data *data,
264 struct run_as_ret *ret_value)
265 {
266 int ret = 0;
267 uint64_t *offsets = NULL;
268 uint32_t num_offset;
269
270 ret_value->_error = false;
271
272 /* On success, this call allocates the offsets paramater. */
273 ret = lttng_elf_get_sdt_probe_offsets(data->fd,
274 data->u.extract_sdt_probe_offsets.provider_name,
275 data->u.extract_sdt_probe_offsets.probe_name,
276 &offsets, &num_offset);
277
278 if (ret) {
279 DBG("Failed to extract SDT probe offsets");
280 ret_value->_error = true;
281 goto end;
282 }
283
284 if (num_offset <= 0 || num_offset > LTTNG_KERNEL_MAX_UPROBE_NUM) {
285 DBG("Wrong number of probes.");
286 ret = -1;
287 ret_value->_error = true;
288 goto free_offset;
289 }
290
291 /* Copy the content of the offsets array to the ret struct. */
292 memcpy(ret_value->u.extract_sdt_probe_offsets.offsets,
293 offsets, num_offset * sizeof(uint64_t));
294
295 ret_value->u.extract_sdt_probe_offsets.num_offset = num_offset;
296
297 free_offset:
298 free(offsets);
299 end:
300 return ret;
301 }
302 #else
303 static
304 int _extract_elf_symbol_offset(struct run_as_data *data,
305 struct run_as_ret *ret_value)
306 {
307 ERR("Unimplemented runas command RUN_AS_EXTRACT_ELF_SYMBOL_OFFSET");
308 return -1;
309 }
310
311 static
312 int _extract_sdt_probe_offsets(struct run_as_data *data,
313 struct run_as_ret *ret_value)
314 {
315 ERR("Unimplemented runas command RUN_AS_EXTRACT_SDT_PROBE_OFFSETS");
316 return -1;
317 }
318 #endif
319
320 static
321 run_as_fct run_as_enum_to_fct(enum run_as_cmd cmd)
322 {
323 switch (cmd) {
324 case RUN_AS_MKDIR:
325 return _mkdir;
326 case RUN_AS_OPEN:
327 return _open;
328 case RUN_AS_UNLINK:
329 return _unlink;
330 case RUN_AS_RMDIR_RECURSIVE:
331 return _rmdir_recursive;
332 case RUN_AS_MKDIR_RECURSIVE:
333 return _mkdir_recursive;
334 case RUN_AS_EXTRACT_ELF_SYMBOL_OFFSET:
335 return _extract_elf_symbol_offset;
336 case RUN_AS_EXTRACT_SDT_PROBE_OFFSETS:
337 return _extract_sdt_probe_offsets;
338 default:
339 ERR("Unknown command %d", (int) cmd);
340 return NULL;
341 }
342 }
343
344 static
345 int do_send_fd(int sock, int fd)
346 {
347 ssize_t len;
348
349 if (fd < 0) {
350 ERR("Attempt to send invalid file descriptor to master (fd = %i)", fd);
351 /* Return 0 as this is not a fatal error. */
352 return 0;
353 }
354
355 len = lttcomm_send_fds_unix_sock(sock, &fd, 1);
356 if (len < 0) {
357 PERROR("lttcomm_send_fds_unix_sock");
358 return -1;
359 }
360 return 0;
361 }
362
363 static
364 int do_recv_fd(int sock, int *fd)
365 {
366 ssize_t len;
367
368 len = lttcomm_recv_fds_unix_sock(sock, fd, 1);
369
370 if (!len) {
371 return -1;
372 } else if (len < 0) {
373 PERROR("lttcomm_recv_fds_unix_sock");
374 return -1;
375 }
376 if (*fd < 0) {
377 ERR("Invalid file descriptor received from worker (fd = %i)", *fd);
378 /* Return 0 as this is not a fatal error. */
379 return 0;
380 }
381
382 return 0;
383 }
384
385 static
386 int send_fd_to_worker(struct run_as_worker *worker, enum run_as_cmd cmd, int fd)
387 {
388 int ret = 0;
389
390 switch (cmd) {
391 case RUN_AS_EXTRACT_ELF_SYMBOL_OFFSET:
392 case RUN_AS_EXTRACT_SDT_PROBE_OFFSETS:
393 break;
394 default:
395 return 0;
396 }
397
398 if (fd < 0) {
399 ERR("Refusing to send invalid fd to worker (fd = %i)", fd);
400 return -1;
401 }
402
403 ret = do_send_fd(worker->sockpair[0], fd);
404 if (ret < 0) {
405 PERROR("do_send_fd");
406 ret = -1;
407 }
408
409 return ret;
410 }
411
412 static
413 int send_fd_to_master(struct run_as_worker *worker, enum run_as_cmd cmd, int fd)
414 {
415 int ret = 0, ret_close = 0;
416
417 switch (cmd) {
418 case RUN_AS_OPEN:
419 break;
420 default:
421 return 0;
422 }
423
424 if (fd < 0) {
425 DBG("Not sending file descriptor to master as it is invalid (fd = %i)", fd);
426 return 0;
427 }
428 ret = do_send_fd(worker->sockpair[1], fd);
429 if (ret < 0) {
430 PERROR("do_send_fd error");
431 ret = -1;
432 }
433
434 ret_close = close(fd);
435 if (ret_close < 0) {
436 PERROR("close");
437 }
438
439 return ret;
440 }
441
442 static
443 int recv_fd_from_worker(struct run_as_worker *worker, enum run_as_cmd cmd, int *fd)
444 {
445 int ret = 0;
446
447 switch (cmd) {
448 case RUN_AS_OPEN:
449 break;
450 default:
451 return 0;
452 }
453
454 ret = do_recv_fd(worker->sockpair[0], fd);
455 if (ret < 0) {
456 PERROR("do_recv_fd error");
457 ret = -1;
458 }
459
460 return ret;
461 }
462
463 static
464 int recv_fd_from_master(struct run_as_worker *worker, enum run_as_cmd cmd, int *fd)
465 {
466 int ret = 0;
467
468 switch (cmd) {
469 case RUN_AS_EXTRACT_ELF_SYMBOL_OFFSET:
470 case RUN_AS_EXTRACT_SDT_PROBE_OFFSETS:
471 break;
472 default:
473 return 0;
474 }
475
476 ret = do_recv_fd(worker->sockpair[1], fd);
477 if (ret < 0) {
478 PERROR("do_recv_fd error");
479 ret = -1;
480 }
481
482 return ret;
483 }
484
485 static
486 int cleanup_received_fd(enum run_as_cmd cmd, int fd)
487 {
488 int ret = 0;
489
490 switch (cmd) {
491 case RUN_AS_EXTRACT_ELF_SYMBOL_OFFSET:
492 case RUN_AS_EXTRACT_SDT_PROBE_OFFSETS:
493 break;
494 default:
495 return 0;
496 }
497
498 if (fd < 0) {
499 return 0;
500 }
501 ret = close(fd);
502 if (ret < 0) {
503 PERROR("close error");
504 ret = -1;
505 }
506
507 return ret;
508 }
509
510 /*
511 * Return < 0 on error, 0 if OK, 1 on hangup.
512 */
513 static
514 int handle_one_cmd(struct run_as_worker *worker)
515 {
516 int ret = 0;
517 struct run_as_data data;
518 ssize_t readlen, writelen;
519 struct run_as_ret sendret;
520 run_as_fct cmd;
521 uid_t prev_euid;
522
523 memset(&sendret, 0, sizeof(sendret));
524 sendret.fd = -1;
525
526 /*
527 * Stage 1: Receive run_as_data struct from the master.
528 * The structure contains the command type and all the parameters needed for
529 * its execution
530 */
531 readlen = lttcomm_recv_unix_sock(worker->sockpair[1], &data,
532 sizeof(data));
533 if (readlen == 0) {
534 /* hang up */
535 ret = 1;
536 goto end;
537 }
538 if (readlen < sizeof(data)) {
539 PERROR("lttcomm_recv_unix_sock error");
540 ret = -1;
541 goto end;
542 }
543
544 cmd = run_as_enum_to_fct(data.cmd);
545 if (!cmd) {
546 ret = -1;
547 goto end;
548 }
549
550 /*
551 * Stage 2: Receive file descriptor from master.
552 * Some commands need a file descriptor as input so if it's needed we
553 * receive the fd using the Unix socket.
554 */
555 ret = recv_fd_from_master(worker, data.cmd, &data.fd);
556 if (ret < 0) {
557 PERROR("recv_fd_from_master error");
558 ret = -1;
559 goto end;
560 }
561
562 prev_euid = getuid();
563 if (data.gid != getegid()) {
564 ret = setegid(data.gid);
565 if (ret < 0) {
566 sendret._error = true;
567 sendret._errno = errno;
568 PERROR("setegid");
569 goto write_return;
570 }
571 }
572 if (data.uid != prev_euid) {
573 ret = seteuid(data.uid);
574 if (ret < 0) {
575 sendret._error = true;
576 sendret._errno = errno;
577 PERROR("seteuid");
578 goto write_return;
579 }
580 }
581
582 /*
583 * Also set umask to 0 for mkdir executable bit.
584 */
585 umask(0);
586
587 /*
588 * Stage 3: Execute the command
589 */
590 ret = (*cmd)(&data, &sendret);
591 if (ret < 0) {
592 DBG("Execution of command returned an error");
593 }
594
595 write_return:
596 ret = cleanup_received_fd(data.cmd, data.fd);
597 if (ret < 0) {
598 ERR("Error cleaning up FD");
599 goto end;
600 }
601
602 /*
603 * Stage 4: Send run_as_ret structure to the master.
604 * This structure contain the return value of the command and the errno.
605 */
606 writelen = lttcomm_send_unix_sock(worker->sockpair[1], &sendret,
607 sizeof(sendret));
608 if (writelen < sizeof(sendret)) {
609 PERROR("lttcomm_send_unix_sock error");
610 ret = -1;
611 goto end;
612 }
613
614 /*
615 * Stage 5: Send file descriptor to the master
616 * Some commands return a file descriptor so if it's needed we pass it back
617 * to the master using the Unix socket.
618 */
619 ret = send_fd_to_master(worker, data.cmd, sendret.fd);
620 if (ret < 0) {
621 DBG("Sending FD to master returned an error");
622 goto end;
623 }
624
625 if (seteuid(prev_euid) < 0) {
626 PERROR("seteuid");
627 ret = -1;
628 goto end;
629 }
630 ret = 0;
631 end:
632 return ret;
633 }
634
635 static
636 int run_as_worker(struct run_as_worker *worker)
637 {
638 int ret;
639 ssize_t writelen;
640 struct run_as_ret sendret;
641 size_t proc_orig_len;
642
643 /*
644 * Initialize worker. Set a different process cmdline.
645 */
646 proc_orig_len = strlen(worker->procname);
647 memset(worker->procname, 0, proc_orig_len);
648 strncpy(worker->procname, DEFAULT_RUN_AS_WORKER_NAME, proc_orig_len);
649
650 ret = lttng_prctl(PR_SET_NAME,
651 (unsigned long) DEFAULT_RUN_AS_WORKER_NAME, 0, 0, 0);
652 if (ret && ret != -ENOSYS) {
653 /* Don't fail as this is not essential. */
654 PERROR("prctl PR_SET_NAME");
655 }
656
657 memset(&sendret, 0, sizeof(sendret));
658
659 writelen = lttcomm_send_unix_sock(worker->sockpair[1], &sendret,
660 sizeof(sendret));
661 if (writelen < sizeof(sendret)) {
662 PERROR("lttcomm_send_unix_sock error");
663 ret = EXIT_FAILURE;
664 goto end;
665 }
666
667 for (;;) {
668 ret = handle_one_cmd(worker);
669 if (ret < 0) {
670 ret = EXIT_FAILURE;
671 goto end;
672 } else if (ret > 0) {
673 break;
674 } else {
675 continue; /* Next command. */
676 }
677 }
678 ret = EXIT_SUCCESS;
679 end:
680 return ret;
681 }
682
683 static
684 int run_as_cmd(struct run_as_worker *worker,
685 enum run_as_cmd cmd,
686 struct run_as_data *data,
687 struct run_as_ret *ret_value,
688 uid_t uid, gid_t gid)
689 {
690 int ret = 0;
691 ssize_t readlen, writelen;
692
693 /*
694 * If we are non-root, we can only deal with our own uid.
695 */
696 if (geteuid() != 0) {
697 if (uid != geteuid()) {
698 ret = -1;
699 ret_value->_errno = EPERM;
700 ERR("Client (%d)/Server (%d) UID mismatch (and sessiond is not root)",
701 (int) uid, (int) geteuid());
702 goto end;
703 }
704 }
705
706 data->cmd = cmd;
707 data->uid = uid;
708 data->gid = gid;
709
710 /*
711 * Stage 1: Send the run_as_data struct to the worker process
712 */
713 writelen = lttcomm_send_unix_sock(worker->sockpair[0], data,
714 sizeof(*data));
715 if (writelen < sizeof(*data)) {
716 PERROR("Error writing message to run_as");
717 ret = -1;
718 ret_value->_errno = EIO;
719 goto end;
720 }
721
722 /*
723 * Stage 2: Send file descriptor to the worker process if needed
724 */
725 ret = send_fd_to_worker(worker, data->cmd, data->fd);
726 if (ret) {
727 PERROR("do_send_fd error");
728 ret = -1;
729 ret_value->_errno = EIO;
730 goto end;
731 }
732
733 /*
734 * Stage 3: Wait for the execution of the command
735 */
736
737 /*
738 * Stage 4: Receive the run_as_ret struct containing the return value and
739 * errno
740 */
741 readlen = lttcomm_recv_unix_sock(worker->sockpair[0], ret_value,
742 sizeof(*ret_value));
743 if (!readlen) {
744 ERR("Run-as worker has hung-up during run_as_cmd");
745 ret = -1;
746 ret_value->_errno = EIO;
747 goto end;
748 } else if (readlen < sizeof(*ret_value)) {
749 PERROR("Error reading response from run_as");
750 ret = -1;
751 ret_value->_errno = errno;
752 goto end;
753 }
754
755 if (ret_value->_error) {
756 /* Skip stage 5 on error as there will be no fd to receive. */
757 goto end;
758 }
759
760 /*
761 * Stage 5: Receive file descriptor if needed
762 */
763 ret = recv_fd_from_worker(worker, data->cmd, &ret_value->fd);
764 if (ret < 0) {
765 ERR("Error receiving fd");
766 ret = -1;
767 ret_value->_errno = EIO;
768 }
769
770 end:
771 return ret;
772 }
773
774 /*
775 * This is for debugging ONLY and should not be considered secure.
776 */
777 static
778 int run_as_noworker(enum run_as_cmd cmd,
779 struct run_as_data *data, struct run_as_ret *ret_value,
780 uid_t uid, gid_t gid)
781 {
782 int ret, saved_errno;
783 mode_t old_mask;
784 run_as_fct fct;
785
786 fct = run_as_enum_to_fct(cmd);
787 if (!fct) {
788 errno = -ENOSYS;
789 ret = -1;
790 goto end;
791 }
792 old_mask = umask(0);
793 ret = fct(data, ret_value);
794 saved_errno = ret_value->_errno;
795 umask(old_mask);
796 errno = saved_errno;
797 end:
798 return ret;
799 }
800
801 static
802 int reset_sighandler(void)
803 {
804 int sig;
805
806 DBG("Resetting run_as worker signal handlers to default");
807 for (sig = 1; sig <= 31; sig++) {
808 (void) signal(sig, SIG_DFL);
809 }
810 return 0;
811 }
812
813 static
814 void worker_sighandler(int sig)
815 {
816 const char *signame;
817
818 /*
819 * The worker will inherit its parent's signals since they are part of
820 * the same process group. However, in the case of SIGINT and SIGTERM,
821 * we want to give the worker a chance to teardown gracefully when its
822 * parent closes the command socket.
823 */
824 switch (sig) {
825 case SIGINT:
826 signame = "SIGINT";
827 break;
828 case SIGTERM:
829 signame = "SIGTERM";
830 break;
831 default:
832 signame = NULL;
833 }
834
835 if (signame) {
836 DBG("run_as worker received signal %s", signame);
837 } else {
838 DBG("run_as_worker received signal %d", sig);
839 }
840 }
841
842 static
843 int set_worker_sighandlers(void)
844 {
845 int ret = 0;
846 sigset_t sigset;
847 struct sigaction sa;
848
849 if ((ret = sigemptyset(&sigset)) < 0) {
850 PERROR("sigemptyset");
851 goto end;
852 }
853
854 sa.sa_handler = worker_sighandler;
855 sa.sa_mask = sigset;
856 sa.sa_flags = 0;
857 if ((ret = sigaction(SIGINT, &sa, NULL)) < 0) {
858 PERROR("sigaction SIGINT");
859 goto end;
860 }
861
862 if ((ret = sigaction(SIGTERM, &sa, NULL)) < 0) {
863 PERROR("sigaction SIGTERM");
864 goto end;
865 }
866
867 DBG("run_as signal handler set for SIGTERM and SIGINT");
868 end:
869 return ret;
870 }
871
872 static
873 int run_as_create_worker_no_lock(const char *procname)
874 {
875 pid_t pid;
876 int i, ret = 0;
877 ssize_t readlen;
878 struct run_as_ret recvret;
879 struct run_as_worker *worker;
880
881 assert(!global_worker);
882 if (!use_clone()) {
883 /*
884 * Don't initialize a worker, all run_as tasks will be performed
885 * in the current process.
886 */
887 ret = 0;
888 goto end;
889 }
890 worker = zmalloc(sizeof(*worker));
891 if (!worker) {
892 ret = -ENOMEM;
893 goto end;
894 }
895 worker->procname = strdup(procname);
896 if (!worker->procname) {
897 ret = -ENOMEM;
898 goto error_procname_alloc;
899 }
900 /* Create unix socket. */
901 if (lttcomm_create_anon_unix_socketpair(worker->sockpair) < 0) {
902 ret = -1;
903 goto error_sock;
904 }
905
906 /* Fork worker. */
907 pid = fork();
908 if (pid < 0) {
909 PERROR("fork");
910 ret = -1;
911 goto error_fork;
912 } else if (pid == 0) {
913 /* Child */
914
915 reset_sighandler();
916
917 set_worker_sighandlers();
918
919 /* Just close, no shutdown. */
920 if (close(worker->sockpair[0])) {
921 PERROR("close");
922 exit(EXIT_FAILURE);
923 }
924
925 /*
926 * Close all FDs aside from STDIN, STDOUT, STDERR and sockpair[1]
927 * Sockpair[1] is used as a control channel with the master
928 */
929 for (i = 3; i < sysconf(_SC_OPEN_MAX); i++) {
930 if (i != worker->sockpair[1]) {
931 (void) close(i);
932 }
933 }
934
935 worker->sockpair[0] = -1;
936 ret = run_as_worker(worker);
937 if (lttcomm_close_unix_sock(worker->sockpair[1])) {
938 PERROR("close");
939 ret = -1;
940 }
941 worker->sockpair[1] = -1;
942 free(worker->procname);
943 free(worker);
944 LOG(ret ? PRINT_ERR : PRINT_DBG, "run_as worker exiting (ret = %d)", ret);
945 exit(ret ? EXIT_FAILURE : EXIT_SUCCESS);
946 } else {
947 /* Parent */
948
949 /* Just close, no shutdown. */
950 if (close(worker->sockpair[1])) {
951 PERROR("close");
952 ret = -1;
953 goto error_fork;
954 }
955 worker->sockpair[1] = -1;
956 worker->pid = pid;
957 /* Wait for worker to become ready. */
958 readlen = lttcomm_recv_unix_sock(worker->sockpair[0],
959 &recvret, sizeof(recvret));
960 if (readlen < sizeof(recvret)) {
961 ERR("readlen: %zd", readlen);
962 PERROR("Error reading response from run_as at creation");
963 ret = -1;
964 goto error_fork;
965 }
966 global_worker = worker;
967 }
968 end:
969 return ret;
970
971 /* Error handling. */
972 error_fork:
973 for (i = 0; i < 2; i++) {
974 if (worker->sockpair[i] < 0) {
975 continue;
976 }
977 if (lttcomm_close_unix_sock(worker->sockpair[i])) {
978 PERROR("close");
979 }
980 worker->sockpair[i] = -1;
981 }
982 error_sock:
983 free(worker->procname);
984 error_procname_alloc:
985 free(worker);
986 return ret;
987 }
988
989 static
990 int run_as_restart_worker(struct run_as_worker *worker)
991 {
992 int ret = 0;
993 char *procname = NULL;
994
995 procname = worker->procname;
996
997 /* Close socket to run_as worker process and clean up the zombie process */
998 run_as_destroy_worker();
999
1000 /* Create a new run_as worker process*/
1001 ret = run_as_create_worker_no_lock(procname);
1002 if (ret < 0 ) {
1003 ERR("Restarting the worker process failed");
1004 ret = -1;
1005 goto err;
1006 }
1007 err:
1008 return ret;
1009 }
1010
1011 static
1012 int run_as(enum run_as_cmd cmd, struct run_as_data *data,
1013 struct run_as_ret *ret_value, uid_t uid, gid_t gid)
1014 {
1015 int ret, saved_errno;
1016
1017 pthread_mutex_lock(&worker_lock);
1018 if (use_clone()) {
1019 DBG("Using run_as worker");
1020
1021 assert(global_worker);
1022
1023 ret = run_as_cmd(global_worker, cmd, data, ret_value, uid, gid);
1024 saved_errno = ret_value->_errno;
1025
1026 /*
1027 * If the worker thread crashed the errno is set to EIO. we log
1028 * the error and start a new worker process.
1029 */
1030 if (ret == -1 && saved_errno == EIO) {
1031 DBG("Socket closed unexpectedly... "
1032 "Restarting the worker process");
1033 ret = run_as_restart_worker(global_worker);
1034 if (ret == -1) {
1035 ERR("Failed to restart worker process.");
1036 goto err;
1037 }
1038 }
1039 } else {
1040 DBG("Using run_as without worker");
1041 ret = run_as_noworker(cmd, data, ret_value, uid, gid);
1042 }
1043 err:
1044 pthread_mutex_unlock(&worker_lock);
1045 return ret;
1046 }
1047
1048 LTTNG_HIDDEN
1049 int run_as_mkdir_recursive(const char *path, mode_t mode, uid_t uid, gid_t gid)
1050 {
1051 struct run_as_data data;
1052 struct run_as_ret ret;
1053
1054 memset(&data, 0, sizeof(data));
1055 memset(&ret, 0, sizeof(ret));
1056 DBG3("mkdir() recursive %s with mode %d for uid %d and gid %d",
1057 path, (int) mode, (int) uid, (int) gid);
1058 strncpy(data.u.mkdir.path, path, PATH_MAX - 1);
1059 data.u.mkdir.path[PATH_MAX - 1] = '\0';
1060 data.u.mkdir.mode = mode;
1061
1062 run_as(RUN_AS_MKDIR_RECURSIVE, &data, &ret, uid, gid);
1063 errno = ret._errno;
1064 return ret.u.mkdir.ret;
1065 }
1066
1067 LTTNG_HIDDEN
1068 int run_as_mkdir(const char *path, mode_t mode, uid_t uid, gid_t gid)
1069 {
1070 struct run_as_data data;
1071 struct run_as_ret ret;
1072
1073 memset(&data, 0, sizeof(data));
1074 memset(&ret, 0, sizeof(ret));
1075
1076 DBG3("mkdir() %s with mode %d for uid %d and gid %d",
1077 path, (int) mode, (int) uid, (int) gid);
1078 strncpy(data.u.mkdir.path, path, PATH_MAX - 1);
1079 data.u.mkdir.path[PATH_MAX - 1] = '\0';
1080 data.u.mkdir.mode = mode;
1081 run_as(RUN_AS_MKDIR, &data, &ret, uid, gid);
1082 errno = ret._errno;
1083 return ret.u.mkdir.ret;
1084 }
1085
1086 LTTNG_HIDDEN
1087 int run_as_open(const char *path, int flags, mode_t mode, uid_t uid, gid_t gid)
1088 {
1089 struct run_as_data data;
1090 struct run_as_ret ret;
1091
1092 memset(&data, 0, sizeof(data));
1093 memset(&ret, 0, sizeof(ret));
1094
1095 DBG3("open() %s with flags %X mode %d for uid %d and gid %d",
1096 path, flags, (int) mode, (int) uid, (int) gid);
1097 strncpy(data.u.open.path, path, PATH_MAX - 1);
1098 data.u.open.path[PATH_MAX - 1] = '\0';
1099 data.u.open.flags = flags;
1100 data.u.open.mode = mode;
1101 run_as(RUN_AS_OPEN, &data, &ret, uid, gid);
1102 errno = ret._errno;
1103 ret.u.open.ret = ret.fd;
1104 return ret.u.open.ret;
1105 }
1106
1107 LTTNG_HIDDEN
1108 int run_as_unlink(const char *path, uid_t uid, gid_t gid)
1109 {
1110 struct run_as_data data;
1111 struct run_as_ret ret;
1112
1113 memset(&data, 0, sizeof(data));
1114 memset(&ret, 0, sizeof(ret));
1115
1116 DBG3("unlink() %s with for uid %d and gid %d",
1117 path, (int) uid, (int) gid);
1118 strncpy(data.u.unlink.path, path, PATH_MAX - 1);
1119 data.u.unlink.path[PATH_MAX - 1] = '\0';
1120 run_as(RUN_AS_UNLINK, &data, &ret, uid, gid);
1121 errno = ret._errno;
1122 return ret.u.unlink.ret;
1123 }
1124
1125 LTTNG_HIDDEN
1126 int run_as_rmdir_recursive(const char *path, uid_t uid, gid_t gid)
1127 {
1128 struct run_as_data data;
1129 struct run_as_ret ret;
1130
1131 memset(&data, 0, sizeof(data));
1132 memset(&ret, 0, sizeof(ret));
1133
1134 DBG3("rmdir_recursive() %s with for uid %d and gid %d",
1135 path, (int) uid, (int) gid);
1136 strncpy(data.u.rmdir_recursive.path, path, PATH_MAX - 1);
1137 data.u.rmdir_recursive.path[PATH_MAX - 1] = '\0';
1138 run_as(RUN_AS_RMDIR_RECURSIVE, &data, &ret, uid, gid);
1139 errno = ret._errno;
1140 return ret.u.rmdir_recursive.ret;
1141 }
1142
1143 LTTNG_HIDDEN
1144 int run_as_extract_elf_symbol_offset(int fd, const char* function,
1145 uid_t uid, gid_t gid, uint64_t *offset)
1146 {
1147 struct run_as_data data;
1148 struct run_as_ret ret;
1149
1150 memset(&data, 0, sizeof(data));
1151 memset(&ret, 0, sizeof(ret));
1152
1153 DBG3("extract_elf_symbol_offset() on fd=%d and function=%s "
1154 "with for uid %d and gid %d", fd, function, (int) uid, (int) gid);
1155
1156 data.fd = fd;
1157
1158 strncpy(data.u.extract_elf_symbol_offset.function, function, LTTNG_SYMBOL_NAME_LEN - 1);
1159
1160 data.u.extract_elf_symbol_offset.function[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
1161
1162 run_as(RUN_AS_EXTRACT_ELF_SYMBOL_OFFSET, &data, &ret, uid, gid);
1163
1164 errno = ret._errno;
1165
1166 if (ret._error) {
1167 return -1;
1168 }
1169
1170 *offset = ret.u.extract_elf_symbol_offset.offset;
1171 return 0;
1172 }
1173
1174 LTTNG_HIDDEN
1175 int run_as_extract_sdt_probe_offsets(int fd, const char* provider_name,
1176 const char* probe_name, uid_t uid, gid_t gid,
1177 uint64_t **offsets, uint32_t *num_offset)
1178 {
1179 struct run_as_data data;
1180 struct run_as_ret ret;
1181
1182 memset(&data, 0, sizeof(data));
1183 memset(&ret, 0, sizeof(ret));
1184
1185 DBG3("extract_sdt_probe_offsets() on fd=%d, probe_name=%s and "
1186 "provider_name=%s with for uid %d and gid %d", fd, probe_name,
1187 provider_name, (int) uid, (int) gid);
1188
1189 data.fd = fd;
1190
1191 strncpy(data.u.extract_sdt_probe_offsets.probe_name, probe_name, LTTNG_SYMBOL_NAME_LEN - 1);
1192 strncpy(data.u.extract_sdt_probe_offsets.provider_name, provider_name, LTTNG_SYMBOL_NAME_LEN - 1);
1193
1194 data.u.extract_sdt_probe_offsets.probe_name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
1195 data.u.extract_sdt_probe_offsets.provider_name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
1196
1197 run_as(RUN_AS_EXTRACT_SDT_PROBE_OFFSETS, &data, &ret, uid, gid);
1198
1199 errno = ret._errno;
1200
1201 if (ret._error) {
1202 return -1;
1203 }
1204
1205 *num_offset = ret.u.extract_sdt_probe_offsets.num_offset;
1206
1207 *offsets = zmalloc(*num_offset * sizeof(uint64_t));
1208 if (!*offsets) {
1209 return -ENOMEM;
1210 }
1211
1212 memcpy(*offsets, ret.u.extract_sdt_probe_offsets.offsets, *num_offset * sizeof(uint64_t));
1213 return 0;
1214 }
1215
1216 LTTNG_HIDDEN
1217 int run_as_create_worker(const char *procname)
1218 {
1219 int ret;
1220
1221 pthread_mutex_lock(&worker_lock);
1222 ret = run_as_create_worker_no_lock(procname);
1223 pthread_mutex_unlock(&worker_lock);
1224 return ret;
1225 }
1226
1227 LTTNG_HIDDEN
1228 void run_as_destroy_worker(void)
1229 {
1230 struct run_as_worker *worker = global_worker;
1231
1232 DBG("Destroying run_as worker");
1233 pthread_mutex_lock(&worker_lock);
1234 if (!worker) {
1235 goto end;
1236 }
1237 /* Close unix socket */
1238 DBG("Closing run_as worker socket");
1239 if (lttcomm_close_unix_sock(worker->sockpair[0])) {
1240 PERROR("close");
1241 }
1242 worker->sockpair[0] = -1;
1243 /* Wait for worker. */
1244 for (;;) {
1245 int status;
1246 pid_t wait_ret;
1247
1248 wait_ret = waitpid(worker->pid, &status, 0);
1249 if (wait_ret < 0) {
1250 if (errno == EINTR) {
1251 continue;
1252 }
1253 PERROR("waitpid");
1254 break;
1255 }
1256
1257 if (WIFEXITED(status)) {
1258 LOG(WEXITSTATUS(status) == 0 ? PRINT_DBG : PRINT_ERR,
1259 DEFAULT_RUN_AS_WORKER_NAME " terminated with status code %d",
1260 WEXITSTATUS(status));
1261 break;
1262 } else if (WIFSIGNALED(status)) {
1263 ERR(DEFAULT_RUN_AS_WORKER_NAME " was killed by signal %d",
1264 WTERMSIG(status));
1265 break;
1266 }
1267 }
1268 free(worker->procname);
1269 free(worker);
1270 global_worker = NULL;
1271 end:
1272 pthread_mutex_unlock(&worker_lock);
1273 }
This page took 0.058182 seconds and 4 git commands to generate.