diff --git a/agent/qrexec-agent-data.c b/agent/qrexec-agent-data.c index 08fb71ff..a37c5438 100644 --- a/agent/qrexec-agent-data.c +++ b/agent/qrexec-agent-data.c @@ -202,7 +202,8 @@ static int handle_just_exec(struct qrexec_parsed_command *cmd) static int handle_new_process_common( int type, int connect_domain, int connect_port, struct qrexec_parsed_command *cmd, - int buffer_size) + int buffer_size, + const char *cmdline_for_logging) { libvchan_t *data_vchan; int exit_code; @@ -257,7 +258,7 @@ static int handle_new_process_common( exit_code = 0; } if (exit_code != 0) { - LOG(ERROR, "failed to spawn process"); + LOG(ERROR, "failed to spawn process (exited %d): %s", exit_code, cmdline_for_logging); /* Send stdout+stderr EOF first, since the service is expected to send * one before exit code in case of MSG_EXEC_CMDLINE. Ignore * libvchan_send error if any, as we're going to terminate soon @@ -271,7 +272,11 @@ static int handle_new_process_common( libvchan_close(data_vchan); return exit_code; } - LOG(INFO, "executed: %s (pid %d)", cmd->cmdline, pid); + if (pid == 0) + LOG(INFO, "executed: %s", cmd->cmdline); + else + LOG(INFO, "executed: %s (pid %d)", cmd->cmdline, pid); + break; default: LOG(ERROR, "unknown request type: %d", type); @@ -317,7 +322,7 @@ static int handle_new_process_common( /* Returns PID of data processing process */ pid_t handle_new_process(int type, int connect_domain, int connect_port, - struct qrexec_parsed_command *cmd) + struct qrexec_parsed_command *cmd, const char *cmdline_for_logging) { int exit_code; pid_t pid; @@ -335,8 +340,7 @@ pid_t handle_new_process(int type, int connect_domain, int connect_port, /* child process */ exit_code = handle_new_process_common(type, connect_domain, connect_port, - cmd, 0); - + cmd, 0, cmdline_for_logging); exit(exit_code); } diff --git a/agent/qrexec-agent.c b/agent/qrexec-agent.c index 5fb4f6f8..2b276427 100644 --- a/agent/qrexec-agent.c +++ b/agent/qrexec-agent.c @@ -596,14 +596,16 @@ static void handle_server_exec_request_init(struct msg_header *hdr) } else { cmd = parse_qubes_rpc_command(params->cmdline, true); if (cmd == NULL) { - LOG(ERROR, "Could not parse command line: %s", params->cmdline); + LOG(ERROR, "Cannot parse command line: %s", params->cmdline); goto doit; } /* load service config only for service requests */ if (cmd->service_descriptor) { if (load_service_config_v2(cmd) < 0) { - LOG(ERROR, "Could not load config for command %s", params->cmdline); + LOG(ERROR, + "Cannot load service configuration: %s+%s", + cmd->service_name, cmd->arg ? cmd->arg : ""); destroy_qrexec_parsed_command(cmd); cmd = NULL; goto doit; @@ -685,7 +687,7 @@ static void handle_server_exec_request_do(int type, /* No fork server case */ child_agent = handle_new_process(type, params->connect_domain, params->connect_port, - cmd); + cmd, cmdline); register_vchan_connection(child_agent, -1, params->connect_domain, params->connect_port); diff --git a/agent/qrexec-agent.h b/agent/qrexec-agent.h index ac6a6440..3cef8589 100644 --- a/agent/qrexec-agent.h +++ b/agent/qrexec-agent.h @@ -42,7 +42,7 @@ extern const bool qrexec_is_fork_server; pid_t handle_new_process(int type, int connect_domain, int connect_port, - struct qrexec_parsed_command *cmd); + struct qrexec_parsed_command *cmd, const char *cmdline_for_logging); int handle_data_client(int type, int connect_domain, int connect_port, diff --git a/agent/qrexec-fork-server.c b/agent/qrexec-fork-server.c index 3ee5c124..0abd696d 100644 --- a/agent/qrexec-fork-server.c +++ b/agent/qrexec-fork-server.c @@ -98,7 +98,7 @@ static void handle_single_command(int fd, struct qrexec_cmd_info *info) { goto fail; handle_new_process(info->type, info->connect_domain, - info->connect_port, cmd); + info->connect_port, cmd, cmdline); destroy_qrexec_parsed_command(cmd); fail: free(cmdline); diff --git a/daemon/qrexec-daemon-common.c b/daemon/qrexec-daemon-common.c index 20529a7f..8cfea93c 100644 --- a/daemon/qrexec-daemon-common.c +++ b/daemon/qrexec-daemon-common.c @@ -429,7 +429,11 @@ int prepare_local_fds(struct qrexec_parsed_command *command, struct buffer *stdi } // See also qrexec-agent/qrexec-agent-data.c -static void handle_failed_exec(libvchan_t *data_vchan, bool is_service, int exit_code) +static void handle_failed_exec( + libvchan_t *data_vchan, + bool is_service, + int exit_code, + const char *cmdline_for_logging) { const struct msg_header hdr[2] = { { @@ -442,7 +446,6 @@ static void handle_failed_exec(libvchan_t *data_vchan, bool is_service, int exit }, }; - LOG(ERROR, "failed to spawn process, exiting"); /* * TODO: In case we fail to execute a *local* process (is_service false), * we should either @@ -455,8 +458,11 @@ static void handle_failed_exec(libvchan_t *data_vchan, bool is_service, int exit * when we support sockets as a local process. */ if (is_service) { + LOG(ERROR, "failed to spawn process for service (exited %d): %s", exit_code, cmdline_for_logging); libvchan_send(data_vchan, hdr, sizeof(hdr)); send_exit_code(data_vchan, exit_code); + } else { + LOG(ERROR, "failed to spawn process for socket (skipping exit %d): %s", exit_code, cmdline_for_logging); } } @@ -524,7 +530,9 @@ int run_qrexec_to_dom0(const struct service_params *svc_params, if (command == NULL) { prepare_ret = -2; } else if (!wait_for_session_maybe(command)) { - LOG(ERROR, "Cannot load service configuration, or forking process failed"); + LOG(ERROR, + "Cannot load service configuration, or forking process failed: %s+%s", + command->service_name, command->arg ? command->arg : ""); prepare_ret = -2; } else { prepare_ret = prepare_local_fds(command, &stdin_buffer); @@ -568,7 +576,7 @@ int handshake_and_go(struct handshake_params *params, if (data_protocol_version >= 0) { if (params->prepare_ret != 0) { rc = params->prepare_ret == -1 ? QREXEC_EXIT_SERVICE_NOT_FOUND : rc; - handle_failed_exec(params->data_vchan, params->remote_send_first, rc); + handle_failed_exec(params->data_vchan, params->remote_send_first, rc, cmd->cmdline); } else { assert((cmd != NULL) == params->remote_send_first); params->data_protocol_version = data_protocol_version; diff --git a/libqrexec/exec.c b/libqrexec/exec.c index a62b6c23..01ebe175 100644 --- a/libqrexec/exec.c +++ b/libqrexec/exec.c @@ -224,7 +224,7 @@ void fix_fds(int fdin, int fdout, int fderr) if (fdin < 0 || fdout < 1 || fderr < 2) { LOG(ERROR, "fix_fds: bad FD numbers: fdin %d, fdout %d, fderr %d", fdin, fdout, fderr); - _exit(125); + _exit(QREXEC_EXIT_PROBLEM); } if ((fdin != 0 && dup2(fdin, 0) < 0) || (fdout != 1 && dup2(fdout, 1) < 0) || diff --git a/libqrexec/log.c b/libqrexec/log.c index f569d3f9..5e605feb 100644 --- a/libqrexec/log.c +++ b/libqrexec/log.c @@ -85,7 +85,7 @@ void setup_logging(const char *program_name) { * FDs breaks if they are not. */ for (int i = 0; i < 3; ++i) { if (fcntl(i, F_GETFD) == -1 && errno == EBADF) - errx(125, "File descriptor %d is closed, cannot continue", i); + errx(QREXEC_EXIT_PROBLEM, "File descriptor %d is closed, cannot continue", i); } /* qrexec_logv() uses several separate fprintf calls, print them at once */ diff --git a/libqrexec/open_logger.c b/libqrexec/open_logger.c index a1d378b4..4a58a360 100644 --- a/libqrexec/open_logger.c +++ b/libqrexec/open_logger.c @@ -29,7 +29,7 @@ int open_logger(struct qrexec_parsed_command *command, int *pid) case 0: fix_fds(pipes[0], 1, 2); execvp("logger", buf); - _exit(126); + _exit(QREXEC_EXIT_REQUEST_REFUSED); default: free(buf[2]); close(pipes[0]);