2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
3 * Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
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.
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
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.
26 #include <sys/types.h>
35 #include <common/common.h>
36 #include <common/utils.h>
37 #include <common/compat/getenv.h>
38 #include <common/compat/prctl.h>
39 #include <common/unix.h>
40 #include <common/defaults.h>
46 typedef int (*run_as_fct
)(struct run_as_data
*data
, struct run_as_ret
*ret_value
);
48 struct run_as_mkdir_data
{
53 struct run_as_open_data
{
59 struct run_as_unlink_data
{
63 struct run_as_rmdir_recursive_data
{
67 struct run_as_mkdir_ret
{
71 struct run_as_open_ret
{
75 struct run_as_unlink_ret
{
79 struct run_as_rmdir_recursive_ret
{
87 RUN_AS_RMDIR_RECURSIVE
,
88 RUN_AS_MKDIR_RECURSIVE
,
95 struct run_as_mkdir_data mkdir
;
96 struct run_as_open_data open
;
97 struct run_as_unlink_data unlink
;
98 struct run_as_rmdir_recursive_data rmdir_recursive
;
105 * The run_as_ret structure holds the returned value and status of the command.
107 * The `u` union field holds the return value of the command; in most cases it
108 * represents the success or the failure of the command. In more complex
109 * commands, it holds a computed value.
111 * The _errno field is the errno recorded after the execution of the command.
113 * The _error fields is used the signify that return status of the command. For
114 * simple commands returning `int` the _error field will be the same as the
115 * ret_int field. In complex commands, it signify the success or failure of the
122 struct run_as_mkdir_ret mkdir
;
123 struct run_as_open_ret open
;
124 struct run_as_unlink_ret unlink
;
125 struct run_as_rmdir_recursive_ret rmdir_recursive
;
131 struct run_as_worker
{
132 pid_t pid
; /* Worker PID. */
137 /* Single global worker per process (for now). */
138 static struct run_as_worker
*global_worker
;
139 /* Lock protecting the worker. */
140 static pthread_mutex_t worker_lock
= PTHREAD_MUTEX_INITIALIZER
;
152 return !lttng_secure_getenv("LTTNG_DEBUG_NOCLONE");
157 int _utils_mkdir_recursive_unsafe(const char *path
, mode_t mode
);
160 * Create recursively directory using the FULL path.
163 int _mkdir_recursive(struct run_as_data
*data
, struct run_as_ret
*ret_value
)
168 path
= data
->u
.mkdir
.path
;
169 mode
= data
->u
.mkdir
.mode
;
171 /* Safe to call as we have transitioned to the requested uid/gid. */
172 ret_value
->u
.mkdir
.ret
= _utils_mkdir_recursive_unsafe(path
, mode
);
173 ret_value
->_errno
= errno
;
174 ret_value
->_error
= (ret_value
->u
.mkdir
.ret
) ? true : false;
175 return ret_value
->u
.mkdir
.ret
;
179 int _mkdir(struct run_as_data
*data
, struct run_as_ret
*ret_value
)
181 ret_value
->u
.mkdir
.ret
= mkdir(data
->u
.mkdir
.path
, data
->u
.mkdir
.mode
);
182 ret_value
->_errno
= errno
;
183 ret_value
->_error
= (ret_value
->u
.mkdir
.ret
) ? true : false;
184 return ret_value
->u
.mkdir
.ret
;
188 int _open(struct run_as_data
*data
, struct run_as_ret
*ret_value
)
190 ret_value
->u
.open
.ret
= open(data
->u
.open
.path
, data
->u
.open
.flags
, data
->u
.open
.mode
);
191 ret_value
->fd
= ret_value
->u
.open
.ret
;
192 ret_value
->_errno
= errno
;
193 ret_value
->_error
= (ret_value
->u
.open
.ret
) ? true : false;
194 return ret_value
->u
.open
.ret
;
198 int _unlink(struct run_as_data
*data
, struct run_as_ret
*ret_value
)
200 ret_value
->u
.unlink
.ret
= unlink(data
->u
.unlink
.path
);
201 ret_value
->_errno
= errno
;
202 ret_value
->_error
= (ret_value
->u
.unlink
.ret
) ? true : false;
203 return ret_value
->u
.unlink
.ret
;
207 int _rmdir_recursive(struct run_as_data
*data
, struct run_as_ret
*ret_value
)
209 ret_value
->u
.rmdir_recursive
.ret
= utils_recursive_rmdir(data
->u
.rmdir_recursive
.path
);
210 ret_value
->_errno
= errno
;
211 ret_value
->_error
= (ret_value
->u
.rmdir_recursive
.ret
) ? true : false;
212 return ret_value
->u
.rmdir_recursive
.ret
;
216 run_as_fct
run_as_enum_to_fct(enum run_as_cmd cmd
)
225 case RUN_AS_RMDIR_RECURSIVE
:
226 return _rmdir_recursive
;
227 case RUN_AS_MKDIR_RECURSIVE
:
228 return _mkdir_recursive
;
230 ERR("Unknown command %d", (int) cmd
);
236 int do_send_fd(int sock
, int fd
)
241 ERR("Invalid file description");
245 len
= lttcomm_send_fds_unix_sock(sock
, &fd
, 1);
247 PERROR("lttcomm_send_fds_unix_sock");
254 int do_recv_fd(int sock
, int *fd
)
259 ERR("Invalid file description");
263 len
= lttcomm_recv_fds_unix_sock(sock
, fd
, 1);
267 } else if (len
< 0) {
268 PERROR("lttcomm_recv_fds_unix_sock");
275 int send_fd_to_worker(struct run_as_worker
*worker
, enum run_as_cmd cmd
, int fd
)
284 ret
= do_send_fd(worker
->sockpair
[0], fd
);
286 PERROR("do_send_fd");
294 int send_fd_to_master(struct run_as_worker
*worker
, enum run_as_cmd cmd
, int fd
)
296 int ret
= 0, ret_close
= 0;
305 ret
= do_send_fd(worker
->sockpair
[1], fd
);
307 PERROR("do_send_fd error");
311 ret_close
= close(fd
);
320 int recv_fd_from_worker(struct run_as_worker
*worker
, enum run_as_cmd cmd
, int *fd
)
331 ret
= do_recv_fd(worker
->sockpair
[0], fd
);
333 PERROR("do_recv_fd error");
341 int recv_fd_from_master(struct run_as_worker
*worker
, enum run_as_cmd cmd
, int *fd
)
350 ret
= do_recv_fd(worker
->sockpair
[1], fd
);
352 PERROR("do_recv_fd error");
360 int cleanup_received_fd(enum run_as_cmd cmd
, int fd
)
371 PERROR("close error");
378 * Return < 0 on error, 0 if OK, 1 on hangup.
381 int handle_one_cmd(struct run_as_worker
*worker
)
384 struct run_as_data data
;
385 ssize_t readlen
, writelen
;
386 struct run_as_ret sendret
;
391 * Stage 1: Receive run_as_data struct from the master.
392 * The structure contains the command type and all the parameters needed for
395 readlen
= lttcomm_recv_unix_sock(worker
->sockpair
[1], &data
,
402 if (readlen
< sizeof(data
)) {
403 PERROR("lttcomm_recv_unix_sock error");
408 cmd
= run_as_enum_to_fct(data
.cmd
);
415 * Stage 2: Receive file descriptor from master.
416 * Some commands need a file descriptor as input so if it's needed we
417 * receive the fd using the Unix socket.
419 ret
= recv_fd_from_master(worker
, data
.cmd
, &data
.fd
);
421 PERROR("recv_fd_from_master error");
426 prev_euid
= getuid();
427 if (data
.gid
!= getegid()) {
428 ret
= setegid(data
.gid
);
434 if (data
.uid
!= prev_euid
) {
435 ret
= seteuid(data
.uid
);
443 * Also set umask to 0 for mkdir executable bit.
448 * Stage 3: Execute the command
450 ret
= (*cmd
)(&data
, &sendret
);
452 DBG("Execution of command returned an error");
456 ret
= cleanup_received_fd(data
.cmd
, data
.fd
);
458 ERR("Error cleaning up FD");
463 * Stage 4: Send run_as_ret structure to the master.
464 * This structure contain the return value of the command and the errno.
466 writelen
= lttcomm_send_unix_sock(worker
->sockpair
[1], &sendret
,
468 if (writelen
< sizeof(sendret
)) {
469 PERROR("lttcomm_send_unix_sock error");
475 * Stage 5: Send file descriptor to the master
476 * Some commands return a file descriptor so if it's needed we pass it back
477 * to the master using the Unix socket.
479 ret
= send_fd_to_master(worker
, data
.cmd
, sendret
.fd
);
481 DBG("Sending FD to master returned an error");
485 if (seteuid(prev_euid
) < 0) {
496 int run_as_worker(struct run_as_worker
*worker
)
500 struct run_as_ret sendret
;
501 size_t proc_orig_len
;
504 * Initialize worker. Set a different process cmdline.
506 proc_orig_len
= strlen(worker
->procname
);
507 memset(worker
->procname
, 0, proc_orig_len
);
508 strncpy(worker
->procname
, DEFAULT_RUN_AS_WORKER_NAME
, proc_orig_len
);
510 ret
= lttng_prctl(PR_SET_NAME
,
511 (unsigned long) DEFAULT_RUN_AS_WORKER_NAME
, 0, 0, 0);
512 if (ret
&& ret
!= -ENOSYS
) {
513 /* Don't fail as this is not essential. */
514 PERROR("prctl PR_SET_NAME");
517 memset(&sendret
, 0, sizeof(sendret
));
519 writelen
= lttcomm_send_unix_sock(worker
->sockpair
[1], &sendret
,
521 if (writelen
< sizeof(sendret
)) {
522 PERROR("lttcomm_send_unix_sock error");
528 ret
= handle_one_cmd(worker
);
532 } else if (ret
> 0) {
535 continue; /* Next command. */
544 int run_as_cmd(struct run_as_worker
*worker
,
546 struct run_as_data
*data
,
547 struct run_as_ret
*ret_value
,
548 uid_t uid
, gid_t gid
)
551 ssize_t readlen
, writelen
;
554 * If we are non-root, we can only deal with our own uid.
556 if (geteuid() != 0) {
557 if (uid
!= geteuid()) {
559 ret_value
->_errno
= EPERM
;
560 ERR("Client (%d)/Server (%d) UID mismatch (and sessiond is not root)",
561 (int) uid
, (int) geteuid());
571 * Stage 1: Send the run_as_data struct to the worker process
573 writelen
= lttcomm_send_unix_sock(worker
->sockpair
[0], data
,
575 if (writelen
< sizeof(*data
)) {
576 PERROR("Error writing message to run_as");
578 ret_value
->_errno
= EIO
;
583 * Stage 2: Send file descriptor to the worker process if needed
585 ret
= send_fd_to_worker(worker
, data
->cmd
, data
->fd
);
587 PERROR("do_send_fd error");
589 ret_value
->_errno
= EIO
;
594 * Stage 3: Wait for the execution of the command
598 * Stage 4: Receive the run_as_ret struct containing the return value and
601 readlen
= lttcomm_recv_unix_sock(worker
->sockpair
[0], ret_value
,
604 ERR("Run-as worker has hung-up during run_as_cmd");
606 ret_value
->_errno
= EIO
;
608 } else if (readlen
< sizeof(*ret_value
)) {
609 PERROR("Error reading response from run_as");
611 ret_value
->_errno
= errno
;
615 * Stage 5: Receive file descriptor if needed
617 ret
= recv_fd_from_worker(worker
, data
->cmd
, &ret_value
->fd
);
619 ERR("Error receiving fd");
621 ret_value
->_errno
= EIO
;
629 * This is for debugging ONLY and should not be considered secure.
632 int run_as_noworker(enum run_as_cmd cmd
,
633 struct run_as_data
*data
, struct run_as_ret
*ret_value
,
634 uid_t uid
, gid_t gid
)
636 int ret
, saved_errno
;
640 fct
= run_as_enum_to_fct(cmd
);
647 ret
= fct(data
, ret_value
);
648 saved_errno
= ret_value
->_errno
;
656 int run_as_restart_worker(struct run_as_worker
*worker
)
659 char *procname
= NULL
;
661 procname
= worker
->procname
;
663 /* Close socket to run_as worker process and clean up the zombie process */
664 run_as_destroy_worker();
666 /* Create a new run_as worker process*/
667 ret
= run_as_create_worker(procname
);
669 ERR("Restarting the worker process failed");
678 int run_as(enum run_as_cmd cmd
, struct run_as_data
*data
,
679 struct run_as_ret
*ret_value
, uid_t uid
, gid_t gid
)
681 int ret
, saved_errno
;
684 DBG("Using run_as worker");
685 pthread_mutex_lock(&worker_lock
);
686 assert(global_worker
);
688 ret
= run_as_cmd(global_worker
, cmd
, data
, ret_value
, uid
, gid
);
689 saved_errno
= ret_value
->_errno
;
691 pthread_mutex_unlock(&worker_lock
);
693 * If the worker thread crashed the errno is set to EIO. we log
694 * the error and start a new worker process.
696 if (ret
== -1 && saved_errno
== EIO
) {
697 DBG("Socket closed unexpectedly... "
698 "Restarting the worker process");
699 ret
= run_as_restart_worker(global_worker
);
702 ERR("Failed to restart worker process.");
707 DBG("Using run_as without worker");
708 ret
= run_as_noworker(cmd
, data
, ret_value
, uid
, gid
);
715 int run_as_mkdir_recursive(const char *path
, mode_t mode
, uid_t uid
, gid_t gid
)
717 struct run_as_data data
;
718 struct run_as_ret ret
;
720 memset(&data
, 0, sizeof(data
));
721 memset(&ret
, 0, sizeof(ret
));
722 DBG3("mkdir() recursive %s with mode %d for uid %d and gid %d",
723 path
, (int) mode
, (int) uid
, (int) gid
);
724 strncpy(data
.u
.mkdir
.path
, path
, PATH_MAX
- 1);
725 data
.u
.mkdir
.path
[PATH_MAX
- 1] = '\0';
726 data
.u
.mkdir
.mode
= mode
;
728 run_as(RUN_AS_MKDIR_RECURSIVE
, &data
, &ret
, uid
, gid
);
730 return ret
.u
.mkdir
.ret
;
734 int run_as_mkdir(const char *path
, mode_t mode
, uid_t uid
, gid_t gid
)
736 struct run_as_data data
;
737 struct run_as_ret ret
;
739 memset(&data
, 0, sizeof(data
));
740 memset(&ret
, 0, sizeof(ret
));
742 DBG3("mkdir() %s with mode %d for uid %d and gid %d",
743 path
, (int) mode
, (int) uid
, (int) gid
);
744 strncpy(data
.u
.mkdir
.path
, path
, PATH_MAX
- 1);
745 data
.u
.mkdir
.path
[PATH_MAX
- 1] = '\0';
746 data
.u
.mkdir
.mode
= mode
;
747 run_as(RUN_AS_MKDIR
, &data
, &ret
, uid
, gid
);
749 return ret
.u
.mkdir
.ret
;
753 int run_as_open(const char *path
, int flags
, mode_t mode
, uid_t uid
, gid_t gid
)
755 struct run_as_data data
;
756 struct run_as_ret ret
;
758 memset(&data
, 0, sizeof(data
));
759 memset(&ret
, 0, sizeof(ret
));
761 DBG3("open() %s with flags %X mode %d for uid %d and gid %d",
762 path
, flags
, (int) mode
, (int) uid
, (int) gid
);
763 strncpy(data
.u
.open
.path
, path
, PATH_MAX
- 1);
764 data
.u
.open
.path
[PATH_MAX
- 1] = '\0';
765 data
.u
.open
.flags
= flags
;
766 data
.u
.open
.mode
= mode
;
767 run_as(RUN_AS_OPEN
, &data
, &ret
, uid
, gid
);
769 ret
.u
.open
.ret
= ret
.fd
;
770 return ret
.u
.open
.ret
;
774 int run_as_unlink(const char *path
, uid_t uid
, gid_t gid
)
776 struct run_as_data data
;
777 struct run_as_ret ret
;
779 memset(&data
, 0, sizeof(data
));
780 memset(&ret
, 0, sizeof(ret
));
782 DBG3("unlink() %s with for uid %d and gid %d",
783 path
, (int) uid
, (int) gid
);
784 strncpy(data
.u
.unlink
.path
, path
, PATH_MAX
- 1);
785 data
.u
.unlink
.path
[PATH_MAX
- 1] = '\0';
786 run_as(RUN_AS_UNLINK
, &data
, &ret
, uid
, gid
);
788 return ret
.u
.unlink
.ret
;
792 int run_as_rmdir_recursive(const char *path
, uid_t uid
, gid_t gid
)
794 struct run_as_data data
;
795 struct run_as_ret ret
;
797 memset(&data
, 0, sizeof(data
));
798 memset(&ret
, 0, sizeof(ret
));
800 DBG3("rmdir_recursive() %s with for uid %d and gid %d",
801 path
, (int) uid
, (int) gid
);
802 strncpy(data
.u
.rmdir_recursive
.path
, path
, PATH_MAX
- 1);
803 data
.u
.rmdir_recursive
.path
[PATH_MAX
- 1] = '\0';
804 run_as(RUN_AS_RMDIR_RECURSIVE
, &data
, &ret
, uid
, gid
);
806 return ret
.u
.rmdir_recursive
.ret
;
810 int reset_sighandler(void)
814 DBG("Resetting run_as worker signal handlers to default");
815 for (sig
= 1; sig
<= 31; sig
++) {
816 (void) signal(sig
, SIG_DFL
);
822 void worker_sighandler(int sig
)
827 * The worker will inherit its parent's signals since they are part of
828 * the same process group. However, in the case of SIGINT and SIGTERM,
829 * we want to give the worker a chance to teardown gracefully when its
830 * parent closes the command socket.
844 DBG("run_as worker received signal %s", signame
);
846 DBG("run_as_worker received signal %d", sig
);
851 int set_worker_sighandlers(void)
857 if ((ret
= sigemptyset(&sigset
)) < 0) {
858 PERROR("sigemptyset");
862 sa
.sa_handler
= worker_sighandler
;
865 if ((ret
= sigaction(SIGINT
, &sa
, NULL
)) < 0) {
866 PERROR("sigaction SIGINT");
870 if ((ret
= sigaction(SIGTERM
, &sa
, NULL
)) < 0) {
871 PERROR("sigaction SIGTERM");
875 DBG("run_as signal handler set for SIGTERM and SIGINT");
881 int run_as_create_worker(char *procname
)
886 struct run_as_ret recvret
;
887 struct run_as_worker
*worker
;
889 pthread_mutex_lock(&worker_lock
);
890 assert(!global_worker
);
893 * Don't initialize a worker, all run_as tasks will be performed
894 * in the current process.
899 worker
= zmalloc(sizeof(*worker
));
904 worker
->procname
= procname
;
905 /* Create unix socket. */
906 if (lttcomm_create_anon_unix_socketpair(worker
->sockpair
) < 0) {
917 } else if (pid
== 0) {
922 set_worker_sighandlers();
924 /* The child has no use for this lock. */
925 pthread_mutex_unlock(&worker_lock
);
926 /* Just close, no shutdown. */
927 if (close(worker
->sockpair
[0])) {
933 * Close all FDs aside from STDIN, STDOUT, STDERR and sockpair[1]
934 * Sockpair[1] is used as a control channel with the master
936 for (i
= 3; i
< sysconf(_SC_OPEN_MAX
); i
++) {
937 if (i
!= worker
->sockpair
[1]) {
942 worker
->sockpair
[0] = -1;
943 ret
= run_as_worker(worker
);
944 if (lttcomm_close_unix_sock(worker
->sockpair
[1])) {
948 worker
->sockpair
[1] = -1;
949 LOG(ret
? PRINT_ERR
: PRINT_DBG
, "run_as worker exiting (ret = %d)", ret
);
950 exit(ret
? EXIT_FAILURE
: EXIT_SUCCESS
);
954 /* Just close, no shutdown. */
955 if (close(worker
->sockpair
[1])) {
960 worker
->sockpair
[1] = -1;
962 /* Wait for worker to become ready. */
963 readlen
= lttcomm_recv_unix_sock(worker
->sockpair
[0],
964 &recvret
, sizeof(recvret
));
965 if (readlen
< sizeof(recvret
)) {
966 ERR("readlen: %zd", readlen
);
967 PERROR("Error reading response from run_as at creation");
971 global_worker
= worker
;
974 pthread_mutex_unlock(&worker_lock
);
977 /* Error handling. */
979 for (i
= 0; i
< 2; i
++) {
980 if (worker
->sockpair
[i
] < 0) {
983 if (lttcomm_close_unix_sock(worker
->sockpair
[i
])) {
986 worker
->sockpair
[i
] = -1;
990 pthread_mutex_unlock(&worker_lock
);
995 void run_as_destroy_worker(void)
997 struct run_as_worker
*worker
= global_worker
;
999 DBG("Destroying run_as worker");
1000 pthread_mutex_lock(&worker_lock
);
1004 /* Close unix socket */
1005 DBG("Closing run_as worker socket");
1006 if (lttcomm_close_unix_sock(worker
->sockpair
[0])) {
1009 worker
->sockpair
[0] = -1;
1010 /* Wait for worker. */
1015 wait_ret
= waitpid(worker
->pid
, &status
, 0);
1017 if (errno
== EINTR
) {
1024 if (WIFEXITED(status
)) {
1025 LOG(WEXITSTATUS(status
) == 0 ? PRINT_DBG
: PRINT_ERR
,
1026 DEFAULT_RUN_AS_WORKER_NAME
" terminated with status code %d",
1027 WEXITSTATUS(status
));
1029 } else if (WIFSIGNALED(status
)) {
1030 ERR(DEFAULT_RUN_AS_WORKER_NAME
" was killed by signal %d",
1036 global_worker
= NULL
;
1038 pthread_mutex_unlock(&worker_lock
);