diff --git a/common/os_calls.c b/common/os_calls.c index f51f47b9..db5d00b4 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -2717,23 +2717,47 @@ g_execvp(const char *p1, char *args[]) g_strnjoin(args_str, ARGS_STR_LEN, " ", (const char **) args, args_len); LOG(LOG_LEVEL_DEBUG, - "Calling exec (executable: %s, arguments: %s)", + "Calling exec (excutable: %s, arguments: %s)", p1, args_str); - g_rm_temp_dir(); rv = execvp(p1, args); /* should not get here */ + int saved_errno = errno; + LOG(LOG_LEVEL_ERROR, - "Error calling exec (executable: %s, arguments: %s) " + "Error calling exec (excutable: %s, arguments: %s) " "returned errno: %d, description: %s", p1, args_str, g_get_errno(), g_get_strerror()); - g_mk_socket_path(0); + errno = saved_errno; return rv; #endif } +/*****************************************************************************/ +int +g_execvp_list(const char *file, struct list *argv) +{ + int rv = -1; + + /* Push a terminating NULL onto the list for the system call */ + if (!list_add_item(argv, (tintptr)NULL)) + { + LOG(LOG_LEVEL_ERROR, "No memory for exec to terminate list"); + errno = ENOMEM; + } + else + { + /* Read the argv argument straight from the list */ + rv = g_execvp(file, (char **)argv->items); + + /* should not get here */ + list_remove_item(argv, argv->count - 1); // Lose terminating NULL + } + return rv; +} + /*****************************************************************************/ /* does not work in win32 */ int diff --git a/common/os_calls.h b/common/os_calls.h index 067da5a6..5304ae66 100644 --- a/common/os_calls.h +++ b/common/os_calls.h @@ -32,6 +32,8 @@ struct exit_status uint8_t signal_no; }; +struct list; + #define g_tcp_can_recv g_sck_can_recv #define g_tcp_can_send g_sck_can_send #define g_tcp_recv g_sck_recv @@ -234,6 +236,18 @@ int g_system(const char *aexec); char *g_get_strerror(void); int g_get_errno(void); int g_execvp(const char *p1, char *args[]); +/** + * Issues an execvp() call + * + * @param file Executable + * @param argv Argument list for executable. + * + * argv does not need to be NULL terminated - the call takes care + * of this. + * + * @return Only if an error has occurred - use g_get_errno() or equivalent + */ +int g_execvp_list(const char *file, struct list *argv); int g_execlp3(const char *a1, const char *a2, const char *a3); unsigned int g_set_alarm(void (*func)(int), unsigned int secs); void g_signal_child_stop(void (*func)(int)); diff --git a/sesman/session.c b/sesman/session.c index 123a29fd..3bfe5860 100644 --- a/sesman/session.c +++ b/sesman/session.c @@ -344,7 +344,7 @@ static int session_start_chansrv(int uid, int display) { struct list *chansrv_params; - char exe_path[262]; + const char *exe_path = XRDP_SBIN_PATH "/xrdp-chansrv"; int chansrv_pid; chansrv_pid = g_fork(); @@ -357,18 +357,15 @@ session_start_chansrv(int uid, int display) chansrv_params->auto_free = 1; /* building parameters */ - g_snprintf(exe_path, sizeof(exe_path), "%s/xrdp-chansrv", - XRDP_SBIN_PATH); list_add_strdup(chansrv_params, exe_path); - list_add_item(chansrv_params, 0); /* mandatory */ env_set_user(uid, 0, display, g_cfg->env_names, g_cfg->env_values); /* executing chansrv */ - g_execvp(exe_path, (char **) (chansrv_params->items)); + g_execvp_list(exe_path, chansrv_params); /* should not get here */ list_delete(chansrv_params); @@ -422,7 +419,6 @@ session_start(struct auth_info *auth_info, char execvpparams[2048]; char *xserver = NULL; /* absolute/relative path to Xorg/Xvnc */ char *passwd_file; - char **pp1 = (char **)NULL; struct session_chain *temp = (struct session_chain *)NULL; struct list *xserver_params = (struct list *)NULL; char authfile[256]; /* The filename for storing xauth information */ @@ -767,11 +763,6 @@ session_start(struct auth_info *auth_info, /* additional parameters from sesman.ini file */ list_append_list_strdup(g_cfg->xorg_params, xserver_params, 1); - /* make sure it ends with a zero */ - list_add_item(xserver_params, 0); - - pp1 = (char **) xserver_params->items; - /* some args are passed via env vars */ g_sprintf(geometry, "%d", s->width); g_setenv("XRDP_START_WIDTH", geometry, 1); @@ -804,10 +795,6 @@ session_start(struct auth_info *auth_info, //config_read_xserver_params(SCP_SESSION_TYPE_XVNC, // xserver_params); list_append_list_strdup(g_cfg->vnc_params, xserver_params, 1); - - /* make sure it ends with a zero */ - list_add_item(xserver_params, 0); - pp1 = (char **)xserver_params->items; } else { @@ -822,7 +809,7 @@ session_start(struct auth_info *auth_info, /* fire up X server */ LOG(LOG_LEVEL_INFO, "Starting X server on display %d: %s", display, dumpItemsToString(xserver_params, execvpparams, 2048)); - g_execvp(xserver, pp1); + g_execvp_list(xserver, xserver_params); /* should not get here */ LOG(LOG_LEVEL_ERROR,