From 1ef47cbf0b2f3e4e06a58517dccfe816365ef941 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Tue, 2 Jul 2019 21:02:09 -0700 Subject: [PATCH] xrdp: fix seg fault when fork on connect and disconnect --- xrdp/xrdp_listen.c | 26 ++++++++++++++++++++++++-- xrdp/xrdp_types.h | 3 ++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/xrdp/xrdp_listen.c b/xrdp/xrdp_listen.c index 97b2eb6c..63e2ca52 100644 --- a/xrdp/xrdp_listen.c +++ b/xrdp/xrdp_listen.c @@ -62,6 +62,7 @@ xrdp_listen_create(void) xrdp_listen_create_pro_done(self); self->trans_list = list_create(); self->process_list = list_create(); + self->fork_list = list_create(); if (g_process_sem == 0) { @@ -99,6 +100,7 @@ xrdp_listen_delete(struct xrdp_listen *self) g_delete_wait_obj(self->pro_done_event); list_delete(self->process_list); + list_delete(self->fork_list); g_free(self); } @@ -248,6 +250,10 @@ xrdp_listen_stop_all_listen(struct xrdp_listen *self) int index; struct trans *ltrans; + if (self->trans_list == NULL) + { + return 0; + } for (index = 0; index < self->trans_list->count; index++) { ltrans = (struct trans *) @@ -748,10 +754,11 @@ xrdp_listen_fork(struct xrdp_listen *self, struct trans *server_trans) process->server_trans = server_trans; g_process = process; xrdp_process_run(0); + tc_sem_dec(g_process_sem); xrdp_process_delete(process); /* mark this process to exit */ g_set_term(1); - return 0; + return 1; } /* parent */ @@ -771,7 +778,8 @@ xrdp_listen_conn_in(struct trans *self, struct trans *new_self) if (lis->startup_params->fork) { - return xrdp_listen_fork(lis, new_self); + list_add_item(lis->fork_list, (intptr_t) new_self); + return 0; } process = xrdp_process_create(lis, lis->pro_done_event); @@ -890,6 +898,20 @@ xrdp_listen_main_loop(struct xrdp_listen *self) { break; } + while (self->fork_list->count > 0) + { + ltrans = (struct trans *) list_get_item(self->fork_list, 0); + list_remove_item(self->fork_list, 0); + if (xrdp_listen_fork(self, ltrans) != 0) + { + cont = 0; + break; + } + } + if (cont == 0) + { + break; + } } /* stop listening */ diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h index d164f95b..b0c8b559 100644 --- a/xrdp/xrdp_types.h +++ b/xrdp/xrdp_types.h @@ -406,7 +406,8 @@ struct xrdp_listen { int status; struct list *trans_list; /* list of struct trans* */ - struct list* process_list; + struct list *process_list; + struct list *fork_list; tbus pro_done_event; struct xrdp_startup_params* startup_params; };