mirror of
https://github.com/winscp/winscp.git
synced 2026-10-24 02:28:55 +03:00
Fixes from PuTTY 0.76
– Avoid crash in MIT Kerberos for Windows on session restart (PuTTY commit d599e3e6) – Close all thread handles returned from CreateThread (ea45d7dc) Source commit: b6e962fefe881e305b84a26001d14642aeed62ba
This commit is contained in:
@@ -98,6 +98,28 @@ const char *gsslogmsg = NULL;
|
||||
|
||||
static void ssh_sspi_bind_fns(struct ssh_gss_library *lib);
|
||||
|
||||
static tree234 *libraries_to_never_unload;
|
||||
static int library_to_never_unload_cmp(void *av, void *bv)
|
||||
{
|
||||
uintptr_t a = (uintptr_t)av, b = (uintptr_t)bv;
|
||||
return a < b ? -1 : a > b ? +1 : 0;
|
||||
}
|
||||
static void ensure_library_tree_exists(void)
|
||||
{
|
||||
if (!libraries_to_never_unload)
|
||||
libraries_to_never_unload = newtree234(library_to_never_unload_cmp);
|
||||
}
|
||||
static bool library_is_in_never_unload_tree(HMODULE module)
|
||||
{
|
||||
ensure_library_tree_exists();
|
||||
return find234(libraries_to_never_unload, module, NULL);
|
||||
}
|
||||
static void add_library_to_never_unload_tree(HMODULE module)
|
||||
{
|
||||
ensure_library_tree_exists();
|
||||
add234(libraries_to_never_unload, module);
|
||||
}
|
||||
|
||||
struct ssh_gss_liblist *ssh_gss_setup(Conf *conf, LogContext *logctx) // MPEXT
|
||||
{
|
||||
HMODULE module;
|
||||
@@ -148,6 +170,23 @@ struct ssh_gss_liblist *ssh_gss_setup(Conf *conf, LogContext *logctx) // MPEXT
|
||||
LOAD_LIBRARY_SEARCH_SYSTEM32 |
|
||||
LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR |
|
||||
LOAD_LIBRARY_SEARCH_USER_DIRS);
|
||||
|
||||
/*
|
||||
* The MIT Kerberos DLL suffers an internal segfault
|
||||
* for some reason if you unload and reload one within
|
||||
* the same process. So, make sure that after we load
|
||||
* this library, we never free it.
|
||||
*
|
||||
* Or rather: after we've loaded it once, if any
|
||||
* _further_ load returns the same module handle, we
|
||||
* immediately free it again (to prevent the Windows
|
||||
* API's internal reference count growing without
|
||||
* bound). But on the other hand we never free it in
|
||||
* ssh_gss_cleanup.
|
||||
*/
|
||||
if (library_is_in_never_unload_tree(module))
|
||||
FreeLibrary(module);
|
||||
add_library_to_never_unload_tree(module);
|
||||
}
|
||||
sfree(buffer);
|
||||
}
|
||||
@@ -291,7 +330,11 @@ void ssh_gss_cleanup(struct ssh_gss_liblist *list)
|
||||
* another SSH instance still using it.
|
||||
*/
|
||||
for (i = 0; i < list->nlibraries; i++) {
|
||||
FreeLibrary((HMODULE)list->libraries[i].handle);
|
||||
if (list->libraries[i].id != 0) {
|
||||
HMODULE module = (HMODULE)list->libraries[i].handle;
|
||||
if (!library_is_in_never_unload_tree(module))
|
||||
FreeLibrary(module);
|
||||
}
|
||||
if (list->libraries[i].id == 2) {
|
||||
/* The 'custom' id involves a dynamically allocated message.
|
||||
* Note that we must cast away the 'const' to free it. */
|
||||
|
||||
@@ -451,11 +451,15 @@ struct handle *handle_input_new(HANDLE handle, handle_inputfn_t gotdata,
|
||||
handles_by_evtomain = newtree234(handle_cmp_evtomain);
|
||||
add234(handles_by_evtomain, h);
|
||||
|
||||
CreateThread(NULL, 0, handle_input_threadfunc,
|
||||
&h->u.i, 0, &in_threadid);
|
||||
{ // WINSCP
|
||||
HANDLE hThread = CreateThread(NULL, 0, handle_input_threadfunc,
|
||||
&h->u.i, 0, &in_threadid);
|
||||
if (hThread)
|
||||
CloseHandle(hThread); /* we don't need the thread handle */
|
||||
h->u.i.busy = true;
|
||||
|
||||
return h;
|
||||
} // WINSCP
|
||||
}
|
||||
|
||||
struct handle *handle_output_new(HANDLE handle, handle_outputfn_t sentdata,
|
||||
@@ -482,10 +486,14 @@ struct handle *handle_output_new(HANDLE handle, handle_outputfn_t sentdata,
|
||||
handles_by_evtomain = newtree234(handle_cmp_evtomain);
|
||||
add234(handles_by_evtomain, h);
|
||||
|
||||
CreateThread(NULL, 0, handle_output_threadfunc,
|
||||
&h->u.o, 0, &out_threadid);
|
||||
{ // WINSCP
|
||||
HANDLE hThread = CreateThread(NULL, 0, handle_output_threadfunc,
|
||||
&h->u.o, 0, &out_threadid);
|
||||
if (hThread)
|
||||
CloseHandle(hThread); /* we don't need the thread handle */
|
||||
|
||||
return h;
|
||||
} // WINSCP
|
||||
}
|
||||
|
||||
struct handle *handle_add_foreign_event(HANDLE event,
|
||||
|
||||
Reference in New Issue
Block a user