From f95152dfc16da32e5b59abdee60ddab209c2a564 Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Tue, 5 Apr 2016 17:35:55 -0500 Subject: [PATCH] fix Linux threads to actually use allocated memory --- c/meterpreter/source/common/thread.c | 187 +++++++++++++-------------- c/meterpreter/source/common/thread.h | 2 +- 2 files changed, 94 insertions(+), 95 deletions(-) diff --git a/c/meterpreter/source/common/thread.c b/c/meterpreter/source/common/thread.c index fb951084..d65d4e46 100644 --- a/c/meterpreter/source/common/thread.c +++ b/c/meterpreter/source/common/thread.c @@ -21,17 +21,16 @@ int __futex_wake(volatile void *ftx, int count); * when using CriticalSections with OpenSSL on some Windows systems. Mutex's are not as optimal * as CriticalSections but they appear to resolve the OpenSSL deadlock issue. */ -LOCK * lock_create( VOID ) +LOCK * lock_create(VOID) { - LOCK * lock = (LOCK *)malloc( sizeof( LOCK ) ); - if( lock != NULL ) + LOCK * lock = calloc(1, sizeof(LOCK)); + if (lock != NULL) { - memset( lock, 0, sizeof( LOCK ) ); #ifdef _WIN32 - lock->handle = CreateMutex( NULL, FALSE, NULL ); + lock->handle = CreateMutex(NULL, FALSE, NULL); #else - pthread_mutex_init(lock->handle, NULL); + pthread_mutex_init(&lock->handle, NULL); #endif } return lock; @@ -40,32 +39,32 @@ LOCK * lock_create( VOID ) /* * Destroy a lock that is no longer required. */ -VOID lock_destroy( LOCK * lock ) +VOID lock_destroy(LOCK * lock) { - if( lock != NULL ) + if (lock != NULL ) { - lock_release( lock ); + lock_release(lock); #ifdef _WIN32 - CloseHandle( lock->handle ); + CloseHandle(lock->handle); #else - pthread_mutex_destroy(lock->handle); + pthread_mutex_destroy(&lock->handle); #endif - free( lock ); + free(lock); } } /* * Acquire a lock and block untill it is acquired. */ -VOID lock_acquire( LOCK * lock ) +VOID lock_acquire(LOCK * lock) { - if( lock != NULL ) { + if (lock != NULL ) { #ifdef _WIN32 - WaitForSingleObject( lock->handle, INFINITE ); + WaitForSingleObject(lock->handle, INFINITE); #else - pthread_mutex_lock(lock->handle); + pthread_mutex_lock(&lock->handle); #endif } } @@ -73,13 +72,13 @@ VOID lock_acquire( LOCK * lock ) /* * Release a lock previously held. */ -VOID lock_release( LOCK * lock ) +VOID lock_release(LOCK * lock) { - if( lock != NULL ) { + if (lock != NULL ) { #ifdef _WIN32 - ReleaseMutex( lock->handle ); + ReleaseMutex(lock->handle); #else - pthread_mutex_unlock(lock->handle); + pthread_mutex_unlock(&lock->handle); #endif } } @@ -89,21 +88,21 @@ VOID lock_release( LOCK * lock ) /* * Create a new event which can be signaled/polled/and blocked on. */ -EVENT * event_create( VOID ) +EVENT * event_create(VOID) { EVENT * event = NULL; - event = (EVENT *)malloc( sizeof( EVENT ) ); - if( event == NULL ) + event = (EVENT *)malloc(sizeof(EVENT)); + if (event == NULL) return NULL; - memset( event, 0, sizeof( EVENT ) ); + memset(event, 0, sizeof(EVENT)); #ifdef _WIN32 - event->handle = CreateEvent( NULL, FALSE, FALSE, NULL ); - if( event->handle == NULL ) + event->handle = CreateEvent(NULL, FALSE, FALSE, NULL); + if (event->handle == NULL) { - free( event ); + free(event); return NULL; } #endif @@ -114,16 +113,16 @@ EVENT * event_create( VOID ) /* * Destroy an event. */ -BOOL event_destroy( EVENT * event ) +BOOL event_destroy(EVENT * event) { - if( event == NULL ) + if (event == NULL) return FALSE; #ifdef _WIN32 - CloseHandle( event->handle ); + CloseHandle(event->handle); #endif - free( event ); + free(event); return TRUE; } @@ -131,15 +130,15 @@ BOOL event_destroy( EVENT * event ) /* * Signal an event. */ -BOOL event_signal( EVENT * event ) +BOOL event_signal(EVENT * event) { - if( event == NULL ) + if (event == NULL) return FALSE; #ifdef _WIN32 - dprintf( "Signalling 0x%x", event->handle ); - if( SetEvent( event->handle ) == 0 ) { - dprintf( "Signalling 0x%x failed %u", event->handle, GetLastError() ); + dprintf("Signalling 0x%x", event->handle); + if (SetEvent(event->handle) == 0) { + dprintf("Signalling 0x%x failed %u", event->handle, GetLastError()); return FALSE; } #else @@ -154,13 +153,13 @@ BOOL event_signal( EVENT * event ) * Poll an event to see if it has been signaled. Set timeout to -1 to block indefinatly. * If timeout is 0 this function does not block but returns immediately. */ -BOOL event_poll( EVENT * event, DWORD timeout ) +BOOL event_poll(EVENT * event, DWORD timeout) { #ifdef _WIN32 - if( event == NULL ) + if (event == NULL) return FALSE; - if( WaitForSingleObject( event->handle, timeout ) == WAIT_OBJECT_0 ) + if (WaitForSingleObject(event->handle, timeout) == WAIT_OBJECT_0) return TRUE; return FALSE; @@ -170,13 +169,13 @@ BOOL event_poll( EVENT * event, DWORD timeout ) // DWORD WINAPI WaitForSingleObject( // __in HANDLE hHandle, // __in DWORD dwMilliseconds - // ); + //); // http://msdn.microsoft.com/en-us/library/ms687032(VS.85).aspx - if( event == NULL ) + if (event == NULL) return FALSE; - if(timeout) { + if (timeout) { struct timespec ts; // XXX, need to verify for -1. below modified from bionic/pthread.c @@ -198,7 +197,7 @@ BOOL event_poll( EVENT * event, DWORD timeout ) // We should behave like an auto-reset event result = event->handle ? TRUE : FALSE; - if( result ) + if (result) event->handle = (HANDLE)0; return result; @@ -210,7 +209,7 @@ BOOL event_poll( EVENT * event, DWORD timeout ) /* * Opens and create a THREAD item for the current/calling thread. */ -THREAD * thread_open( VOID ) +THREAD * thread_open(VOID) { THREAD * thread = NULL; #ifdef _WIN32 @@ -218,10 +217,10 @@ THREAD * thread_open( VOID ) HMODULE hKernel32 = NULL; - thread = (THREAD *)malloc( sizeof( THREAD ) ); - if( thread != NULL ) + thread = (THREAD *)malloc(sizeof(THREAD)); + if (thread != NULL) { - memset( thread, 0, sizeof(THREAD) ); + memset(thread, 0, sizeof(THREAD)); thread->id = GetCurrentThreadId(); thread->sigterm = event_create(); @@ -231,41 +230,41 @@ THREAD * thread_open( VOID ) // for now. // First we try to use the normal OpenThread function, available on Windows 2000 and up... - hKernel32 = LoadLibrary( "kernel32.dll" ); - pOpenThread = (OPENTHREAD)GetProcAddress( hKernel32, "OpenThread" ); - if( pOpenThread ) + hKernel32 = LoadLibrary("kernel32.dll"); + pOpenThread = (OPENTHREAD)GetProcAddress(hKernel32, "OpenThread"); + if (pOpenThread) { - thread->handle = pOpenThread( THREAD_TERMINATE|THREAD_SUSPEND_RESUME, FALSE, thread->id ); + thread->handle = pOpenThread(THREAD_TERMINATE|THREAD_SUSPEND_RESUME, FALSE, thread->id); } else { NTOPENTHREAD pNtOpenThread = NULL; // If we can't use OpenThread, we try the older NtOpenThread function as found on NT4 machines. - HMODULE hNtDll = LoadLibrary( "ntdll.dll" ); - pNtOpenThread = (NTOPENTHREAD)GetProcAddress( hNtDll, "NtOpenThread" ); - if( pNtOpenThread ) + HMODULE hNtDll = LoadLibrary("ntdll.dll"); + pNtOpenThread = (NTOPENTHREAD)GetProcAddress(hNtDll, "NtOpenThread"); + if (pNtOpenThread) { _OBJECT_ATTRIBUTES oa = {0}; _CLIENT_ID cid = {0}; cid.UniqueThread = (PVOID)thread->id; - pNtOpenThread( &thread->handle, THREAD_TERMINATE|THREAD_SUSPEND_RESUME, &oa, &cid ); + pNtOpenThread(&thread->handle, THREAD_TERMINATE|THREAD_SUSPEND_RESUME, &oa, &cid); } - FreeLibrary( hNtDll ); + FreeLibrary(hNtDll); } - FreeLibrary( hKernel32 ); + FreeLibrary(hKernel32); } return thread; #else - thread = (THREAD *)malloc( sizeof( THREAD ) ); + thread = (THREAD *)malloc(sizeof(THREAD)); - if( thread != NULL ) + if (thread != NULL) { - memset( thread, 0, sizeof(THREAD) ); + memset(thread, 0, sizeof(THREAD)); thread->id = gettid(); thread->sigterm = event_create(); @@ -320,7 +319,7 @@ void *__paused_thread(void *req) thread = tc->thread; free(tc); - if(event_poll(thread->sigterm, 0) == TRUE) { + if (event_poll(thread->sigterm, 0) == TRUE) { /* * In some cases, we might want to stop a thread before it does anything :/ */ @@ -334,23 +333,23 @@ void *__paused_thread(void *req) /* * Create a new thread in a suspended state. */ -THREAD * thread_create( THREADFUNK funk, LPVOID param1, LPVOID param2, LPVOID param3 ) +THREAD * thread_create(THREADFUNK funk, LPVOID param1, LPVOID param2, LPVOID param3) { THREAD * thread = NULL; - if( funk == NULL ) + if (funk == NULL) return NULL; - thread = (THREAD *)malloc( sizeof( THREAD ) ); - if( thread == NULL ) + thread = (THREAD *)malloc(sizeof(THREAD)); + if (thread == NULL) return NULL; - memset( thread, 0, sizeof( THREAD ) ); + memset(thread, 0, sizeof(THREAD)); thread->sigterm = event_create(); - if( thread->sigterm == NULL ) + if (thread->sigterm == NULL) { - free( thread ); + free(thread); return NULL; } @@ -360,12 +359,12 @@ THREAD * thread_create( THREADFUNK funk, LPVOID param1, LPVOID param2, LPVOID pa thread->parameter3 = param3; #ifdef _WIN32 - thread->handle = CreateThread( NULL, 0, funk, thread, CREATE_SUSPENDED, &thread->id ); + thread->handle = CreateThread(NULL, 0, funk, thread, CREATE_SUSPENDED, &thread->id); - if( thread->handle == NULL ) + if (thread->handle == NULL) { - event_destroy( thread->sigterm ); - free( thread ); + event_destroy(thread->sigterm); + free(thread); return NULL; } @@ -381,13 +380,13 @@ THREAD * thread_create( THREADFUNK funk, LPVOID param1, LPVOID param2, LPVOID pa struct thread_conditional *tc; tc = (struct thread_conditional *) malloc(sizeof(struct thread_conditional)); - if( tc == NULL ) { + if (tc == NULL) { event_destroy(thread->sigterm); free(thread); return NULL; } - memset( tc, 0, sizeof(struct thread_conditional)); + memset(tc, 0, sizeof(struct thread_conditional)); pthread_mutex_init(&tc->suspend_mutex, NULL); pthread_cond_init(&tc->suspend_cond, NULL); @@ -397,7 +396,7 @@ THREAD * thread_create( THREADFUNK funk, LPVOID param1, LPVOID param2, LPVOID pa thread->suspend_thread_data = (void *)(tc); - if(pthread_create(&(thread->pid), NULL, __paused_thread, tc) == -1) { + if (pthread_create(&(thread->pid), NULL, __paused_thread, tc) == -1) { free(tc); event_destroy(thread->sigterm); free(thread); @@ -414,13 +413,13 @@ THREAD * thread_create( THREADFUNK funk, LPVOID param1, LPVOID param2, LPVOID pa /* * Run a thread. */ -BOOL thread_run( THREAD * thread ) +BOOL thread_run(THREAD * thread) { - if( thread == NULL ) + if (thread == NULL) return FALSE; #ifdef _WIN32 - if( ResumeThread( thread->handle ) < 0 ) + if (ResumeThread(thread->handle) < 0) return FALSE; #else @@ -440,14 +439,14 @@ BOOL thread_run( THREAD * thread ) * Signals the thread to terminate. It is the responsibility of the thread to wait for and process this signal. * Should be used to signal the thread to terminate. */ -BOOL thread_sigterm( THREAD * thread ) +BOOL thread_sigterm(THREAD * thread) { BOOL ret; - if( thread == NULL ) + if (thread == NULL) return FALSE; - ret = event_signal( thread->sigterm ); + ret = event_signal(thread->sigterm); #ifndef _WIN32 /* @@ -456,7 +455,7 @@ BOOL thread_sigterm( THREAD * thread ) * * Therefore, we need to start the thread executing before calling thread_join */ - if(thread->thread_started != TRUE) { + if (thread->thread_started != TRUE) { thread_run(thread); } #endif @@ -467,13 +466,13 @@ BOOL thread_sigterm( THREAD * thread ) /* * Terminate a thread. Use with caution! better to signal your thread to terminate and wait for it to do so. */ -BOOL thread_kill( THREAD * thread ) +BOOL thread_kill(THREAD * thread) { - if( thread == NULL ) + if (thread == NULL) return FALSE; #ifdef _WIN32 - if( TerminateThread( thread->handle, -1 ) == 0 ) + if (TerminateThread(thread->handle, -1) == 0) return FALSE; return TRUE; @@ -498,18 +497,18 @@ BOOL thread_kill( THREAD * thread ) /* * Blocks untill the thread has terminated. */ -BOOL thread_join( THREAD * thread ) +BOOL thread_join(THREAD * thread) { - if( thread == NULL ) + if (thread == NULL) return FALSE; #ifdef _WIN32 - if( WaitForSingleObject( thread->handle, INFINITE ) == WAIT_OBJECT_0 ) + if (WaitForSingleObject(thread->handle, INFINITE) == WAIT_OBJECT_0) return TRUE; return FALSE; #else - if(pthread_join(thread->pid, NULL) == 0) + if (pthread_join(thread->pid, NULL) == 0) return TRUE; return FALSE; @@ -520,20 +519,20 @@ BOOL thread_join( THREAD * thread ) * Destroys a previously created thread. Note, this does not terminate the thread. You must signal your * thread to terminate and wait for it to do so (via thread_signal/thread_join). */ -BOOL thread_destroy( THREAD * thread ) +BOOL thread_destroy(THREAD * thread) { - if( thread == NULL ) + if (thread == NULL) return FALSE; - event_destroy( thread->sigterm ); + event_destroy(thread->sigterm); #ifdef _WIN32 - CloseHandle( thread->handle ); + CloseHandle(thread->handle); #else pthread_detach(thread->pid); #endif - free( thread ); + free(thread); return TRUE; } diff --git a/c/meterpreter/source/common/thread.h b/c/meterpreter/source/common/thread.h index 53888afa..7b2c7e9a 100644 --- a/c/meterpreter/source/common/thread.h +++ b/c/meterpreter/source/common/thread.h @@ -44,7 +44,7 @@ typedef struct _LOCK #ifdef _WIN32 HANDLE handle; #else - pthread_mutex_t *handle; + pthread_mutex_t handle; #endif // _WIN32 } LOCK, * LPLOCK;