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
This commit is contained in:
Michael Gernoth 2006-11-03 19:56:42 +00:00
parent 659a1e062b
commit 8419d91138
4 changed files with 33 additions and 9 deletions

View File

@ -309,6 +309,8 @@ void scardSetInfo(uint32 device, uint32 id, uint32 bytes_out);
int scard_enum_devices(uint32 * id, char *optarg); int scard_enum_devices(uint32 * id, char *optarg);
void scard_tcp_lock(void); void scard_tcp_lock(void);
void scard_tcp_unlock(void); void scard_tcp_unlock(void);
void scard_sec_lock(void);
void scard_sec_unlock(void);
STREAM scard_tcp_init(void); STREAM scard_tcp_init(void);
void scard_tcp_connect(void); void scard_tcp_connect(void);
void scard_tcp_reset_state(void); void scard_tcp_reset_state(void);

View File

@ -66,7 +66,11 @@ extern DEVICE_FNS scard_fns;
extern FILEINFO g_fileinfo[]; extern FILEINFO g_fileinfo[];
extern BOOL g_notify_stamp; extern BOOL g_notify_stamp;
#ifdef WITH_SCARD
VCHANNEL *rdpdr_channel;
#else
static VCHANNEL *rdpdr_channel; static VCHANNEL *rdpdr_channel;
#endif
/* If select() times out, the request for the device with handle g_min_timeout_fd is aborted */ /* If select() times out, the request for the device with handle g_min_timeout_fd is aborted */
NTHANDLE g_min_timeout_fd; NTHANDLE g_min_timeout_fd;

28
scard.c
View File

@ -45,6 +45,7 @@
static struct stream out[STREAM_COUNT]; static struct stream out[STREAM_COUNT];
static int cur_stream_id = 0; static int cur_stream_id = 0;
static pthread_mutex_t *tcp_sendcontrol_mutex = NULL; 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 uint32 curDevice = 0, curId = 0, curBytesOut = 0;
static PSCNameMapRec nameMapList = NULL; static PSCNameMapRec nameMapList = NULL;
@ -54,7 +55,6 @@ static pthread_t queueHandler;
static pthread_mutex_t queueAccess; static pthread_mutex_t queueAccess;
static pthread_mutex_t queueEmpty; static pthread_mutex_t queueEmpty;
static pthread_mutex_t hcardAccess; static pthread_mutex_t hcardAccess;
static pthread_mutex_t sendControl;
static PMEM_HANDLE threadListHandle = NULL; static PMEM_HANDLE threadListHandle = NULL;
static PThreadListElement threadList = NULL; static PThreadListElement threadList = NULL;
@ -152,12 +152,6 @@ scard_enum_devices(uint32 * id, char *optarg)
return 0; return 0;
} }
if (0 != pthread_mutex_init(&sendControl, NULL))
{
error("[SMART CARD: Can't initialize send control mutex]\n");
return 0;
}
if (0 != if (0 !=
pthread_create(&queueHandler, NULL, (void *(*)(void *)) queue_handler_function, NULL)) pthread_create(&queueHandler, NULL, (void *(*)(void *)) queue_handler_function, NULL))
{ {
@ -2497,9 +2491,7 @@ SC_deviceControl(PSCThreadData data)
size_t buffer_len = 0; size_t buffer_len = 0;
scard_device_control(data->handle, data->request, data->in, data->out); scard_device_control(data->handle, data->request, data->in, data->out);
buffer_len = (size_t) data->out->p - (size_t) data->out->data; 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); rdpdr_send_completion(data->device, data->id, 0, buffer_len, data->out->data, buffer_len);
pthread_mutex_unlock(&sendControl);
SC_destroyThreadData(data); SC_destroyThreadData(data);
} }
@ -2645,6 +2637,24 @@ scard_tcp_unlock(void)
pthread_mutex_unlock(tcp_sendcontrol_mutex); 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 STREAM
scard_tcp_init(void) scard_tcp_init(void)
{ {

View File

@ -362,6 +362,10 @@ sec_send_to_channel(STREAM s, uint32 flags, uint16 channel)
{ {
int datalen; int datalen;
#ifdef WITH_SCARD
scard_sec_lock();
#endif
s_pop_layer(s, sec_hdr); s_pop_layer(s, sec_hdr);
if (!g_licence_issued || (flags & SEC_ENCRYPT)) if (!g_licence_issued || (flags & SEC_ENCRYPT))
out_uint32_le(s, flags); 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); mcs_send_to_channel(s, channel);
#ifdef WITH_SCARD
scard_sec_unlock();
#endif
} }
/* Transmit secure transport packet */ /* Transmit secure transport packet */