From 8419d911384eafc4ccf01148ea49b60ecfa67042 Mon Sep 17 00:00:00 2001 From: Michael Gernoth Date: Fri, 3 Nov 2006 19:56:42 +0000 Subject: [PATCH] make sure to lock the datapath of rdpdr_send_completion to prevent simultaneous access to shared variables in multiple threads git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@1326 423420c4-83ab-492f-b58f-81f9feb106b5 --- proto.h | 2 ++ rdpdr.c | 4 ++++ scard.c | 28 +++++++++++++++++++--------- secure.c | 8 ++++++++ 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/proto.h b/proto.h index b9ed1e5..5b1efd5 100644 --- a/proto.h +++ b/proto.h @@ -309,6 +309,8 @@ void scardSetInfo(uint32 device, uint32 id, uint32 bytes_out); int scard_enum_devices(uint32 * id, char *optarg); void scard_tcp_lock(void); void scard_tcp_unlock(void); +void scard_sec_lock(void); +void scard_sec_unlock(void); STREAM scard_tcp_init(void); void scard_tcp_connect(void); void scard_tcp_reset_state(void); diff --git a/rdpdr.c b/rdpdr.c index d7e4633..3e8b162 100644 --- a/rdpdr.c +++ b/rdpdr.c @@ -66,7 +66,11 @@ extern DEVICE_FNS scard_fns; extern FILEINFO g_fileinfo[]; extern BOOL g_notify_stamp; +#ifdef WITH_SCARD +VCHANNEL *rdpdr_channel; +#else static VCHANNEL *rdpdr_channel; +#endif /* If select() times out, the request for the device with handle g_min_timeout_fd is aborted */ NTHANDLE g_min_timeout_fd; diff --git a/scard.c b/scard.c index b2777ec..e3a97df 100644 --- a/scard.c +++ b/scard.c @@ -45,6 +45,7 @@ static struct stream out[STREAM_COUNT]; static int cur_stream_id = 0; static pthread_mutex_t *tcp_sendcontrol_mutex = NULL; +static pthread_mutex_t *sec_channels_mutex = NULL; static uint32 curDevice = 0, curId = 0, curBytesOut = 0; static PSCNameMapRec nameMapList = NULL; @@ -54,7 +55,6 @@ static pthread_t queueHandler; static pthread_mutex_t queueAccess; static pthread_mutex_t queueEmpty; static pthread_mutex_t hcardAccess; -static pthread_mutex_t sendControl; static PMEM_HANDLE threadListHandle = NULL; static PThreadListElement threadList = NULL; @@ -152,12 +152,6 @@ scard_enum_devices(uint32 * id, char *optarg) return 0; } - if (0 != pthread_mutex_init(&sendControl, NULL)) - { - error("[SMART CARD: Can't initialize send control mutex]\n"); - return 0; - } - if (0 != pthread_create(&queueHandler, NULL, (void *(*)(void *)) queue_handler_function, NULL)) { @@ -2497,9 +2491,7 @@ SC_deviceControl(PSCThreadData data) size_t buffer_len = 0; scard_device_control(data->handle, data->request, data->in, data->out); buffer_len = (size_t) data->out->p - (size_t) data->out->data; - pthread_mutex_lock(&sendControl); rdpdr_send_completion(data->device, data->id, 0, buffer_len, data->out->data, buffer_len); - pthread_mutex_unlock(&sendControl); SC_destroyThreadData(data); } @@ -2645,6 +2637,24 @@ scard_tcp_unlock(void) pthread_mutex_unlock(tcp_sendcontrol_mutex); } +void +scard_sec_lock(void) +{ + if (!sec_channels_mutex) + { + sec_channels_mutex = (pthread_mutex_t *) xmalloc(sizeof(pthread_mutex_t)); + pthread_mutex_init(sec_channels_mutex, NULL); + } + + pthread_mutex_lock(sec_channels_mutex); +} + +void +scard_sec_unlock(void) +{ + pthread_mutex_unlock(sec_channels_mutex); +} + STREAM scard_tcp_init(void) { diff --git a/secure.c b/secure.c index 55d765c..2870bab 100644 --- a/secure.c +++ b/secure.c @@ -362,6 +362,10 @@ sec_send_to_channel(STREAM s, uint32 flags, uint16 channel) { int datalen; +#ifdef WITH_SCARD + scard_sec_lock(); +#endif + s_pop_layer(s, sec_hdr); if (!g_licence_issued || (flags & SEC_ENCRYPT)) out_uint32_le(s, flags); @@ -381,6 +385,10 @@ sec_send_to_channel(STREAM s, uint32 flags, uint16 channel) } mcs_send_to_channel(s, channel); + +#ifdef WITH_SCARD + scard_sec_unlock(); +#endif } /* Transmit secure transport packet */