Beispiel #1
0
void *double_killer(void *cookie)
{
	unsigned long long start;
	struct cond_mutex *cm = cookie;

	start = rt_timer_tsc();
	check("mutex_lock", mutex_lock(cm->mutex), 0);
	check_sleep("mutex_lock", start);
	check("thread_kill 1", thread_kill(cm->tid, SIGRTMIN), 0);
	thread_msleep(10);
	check("thread_kill 2", thread_kill(cm->tid, SIGRTMIN), 0);
	check("mutex_unlock", mutex_unlock(cm->mutex), 0);

	return NULL;
}
Beispiel #2
0
/* user interface */
void* server_mgr(void* args)
{
	char buf[128];

	while (1) {
		printf(">>");
		fgets(buf, 128, stdin);
		trim(buf);
		if (strncmp(buf, "add ", 4) == 0)
			mgr_add(buf+4);

		else if (strcmp(buf, "count current") == 0) {
			printf("There are %d user(s) now.\n", mgr_cntcur());
		}
		else if (strcmp(buf, "count all") == 0) {
			printf("There are %d visitor(s) in history.\n", mgr_cntall());
		}
		else if (strncmp(buf, "kill ", 5) == 0)
			thread_kill(buf+5);
		else if (strcmp(buf, "stat all") == 0)
			mgr_statall();
		else if (strncmp(buf, "stat ", 5) == 0)
			mgr_stat(buf+5);

		else 
			printf("Error Command\n");

	}
}
Beispiel #3
0
/* Close up shop. */
void
network_pcap_close(void)
{
    pcap_t *pc;

    if (pcap != NULL) {
	pclog("Closing WinPcap\n");

	/* Tell the polling thread to shut down. */
	pc = pcap; pcap = NULL;
#if 1
	/* Terminate the polling thread. */
	if (poll_tid != NULL) {
		thread_kill(poll_tid);
		poll_tid = NULL;
	}
#else
	/* Wait for the polling thread to shut down. */
	while (poll_tid != NULL)
		;
#endif

	/* OK, now shut down WinPcap itself. */
	f_pcap_close(pc);

	/* Unload the DLL if possible. */
	if (pcap_handle != NULL) {
		dynld_close(pcap_handle);
		pcap_handle = NULL;
	}
    }
    poll_rx = NULL;
    poll_arg = NULL;
}
Beispiel #4
0
void thread_free(THREAD *self) {
	assert(self);

	if (self->status == THREAD_STATUS_RUNNING) {
		thread_cancel(self);
		int count;
		while (self->status == THREAD_STATUS_RUNNING && count++ < 100) {
			usleep(1000);
		}
		if (self->status == THREAD_STATUS_RUNNING) {
			thread_kill(self);
		}
	}

	pthread_join(*(self->thread), NULL);

	if (self->thread) {
		free(self->thread);
		self->thread = NULL;
	}
	

	free(self);
	self = NULL;
}
Beispiel #5
0
main()
{
  long tid1, tid2;
  tid1 = thread_create(thread1, 0);
  tid2 = thread_create(thread2, 0);

  if (thread_kill(tid1) != 1) 
    fprintf(stderr, "** Incorrect return value for successful kill\n");
  if (thread_kill(tid1+456) != 0) 
    fprintf(stderr, "** Incorrect return value for unsuccessful kill\n");

//  thread_kill(tid2);

  if (thread_kill(thread_self()) == 1)
    fprintf(stderr, "** incorrect return value for attempt to kill main\n");
  status(0,2);
  thread_kill(tid2);
  status(1,2);
  thread_yield();
  status(2,2);
}
Beispiel #6
0
main()
{
  long tid1, tid2;

  tid1 = thread_create(thread1, 0);
  tid2 = thread_create(thread2, 0);
  status(0,5);
  thread_yield();
  status(3,5);
  thread_kill(tid2);
  thread_yield();
  status(5,5);
}
Beispiel #7
0
void kernel_done()
{
    uint8_t i;

    for (i = 0; i < THREAD_TID_INVALID; i++) {
        if (get_thread(i)) {
            thread_kill(i);
        }
    }

    kprintf("system shutdown is complete.\n");
    while (1) {
    };
}
/*
 * core_shutdown
 * -----------------
 *
 */
DWORD remote_request_core_shutdown(Remote *remote, Packet *packet)
{
	Channel *channel = NULL;
	Packet *response = packet_create_response(packet);
	DWORD result = ERROR_SUCCESS;

	// Acknowledge the shutdown request
	packet_add_tlv_bool(response, TLV_TYPE_BOOL, TRUE);

	// Transmit the response
	packet_transmit_response(result, remote, response);

#ifdef _WIN32
// see note about posix above - egypt
	dprintf("[SHUTDOWN] Shutting down the Meterpreter thread 1 (killing the main thread)...");
	thread_kill( serverThread );
#endif
	return result;
}
Beispiel #9
0
void sigANY(int sig){
	ThreadSig *ts;
	vfuncp func;
	int tid = TID;
	int tix;
	int ti;

	signal(sig,sigANY); /* for non-BSD */
	tix = 1+getthreadix();
	nsig++;

/*
putfLog("####SIG(%d) tix[%d] *%d",sig,tix,nsig);
VStrSIG();
*/

	if( lTHREADSIG() )
	fprintf(stderr,"-- %X[%d] %d#gotsig %d\n",tid,tix,nsig,sig);

	if( sig < 0 || 32 <= sig ){
		fprintf(stderr,"-- %X[%d] %d#gotsig %d BAD\n",tid,tix,nsig,sig);
		return;
	}
	ts = &sigs[tix][sig];
	if( ts->ts_stat == 0 || ts->ts_func == sigIGNORE ){
		for( ti = 0; ti < MAX_THREADS; ti++ ){
			ts = &sigs[1+ti][sig];
			if( ts->ts_stat && ts->ts_func != sigIGNORE ){
				if( ti != tix ){
			fprintf(stderr,"-- %X[%d] gotsig %d FORW >>> %X[%d] %s:%d\n",
			tid,tix,sig,ts->ts_tid,1+ti,
			ts->ts_F,ts->ts_L);
					if( isWindows() ){
					  /* thread_kill not implemented yet */
					}else{
					thread_kill(ts->ts_tid,sig);
					return;
					}
				}
				break;
			}
			ts = 0;
		}
		if( ts == 0 ){
			ts = &sigs[0][sig];
		}
	}
	if( ts->ts_stat == 0 ){
		fprintf(stderr,"-- %X[%d] %d#gotsig %d UNDEF ????\n",
			tid,tix,nsig,sig);
		return;
	}
	func = ts->ts_func;
	if( func == SIG_DFL ){
		fprintf(stderr,"-- %X[%d] %d#gotsig %d DEFAULT <= %s:%d\n",
			tid,tix,nsig,sig,TS_FL);
	}else
	if( func == SIG_IGN ){
		fprintf(stderr,"-- %X[%d] %d#gotsig %d IGNORED <= %s:%d\n",
			tid,tix,nsig,sig,TS_FL);
	}else{
		if( lTHREADSIG() )
		fprintf(stderr,"-- %X[%d] %d#gotsig %d HANDLED <= %s:%d %X\n",
			tid,tix,nsig,sig,TS_FL,xp2i(func));
		(*func)(sig);
		if( lTHREADSIG() )
		fprintf(stderr,"-- %X[%d] %d#gotsig %d HANDLED <= %s:%d %X\n",
			tid,tix,nsig,sig,TS_FL,xp2i(func));
	}
	if( sig == SIGSEGV ){
		void msleep(int);
		msleep(250);
	}
}
Beispiel #10
0
/*
 * Setup and run the server. This is called from Init via the loader.
 */
DWORD server_setup( SOCKET fd )
{
	Remote * remote        = NULL;
	char cStationName[256] = {0};
	char cDesktopName[256] = {0};
	DWORD res              = 0;

	dprintf("[SERVER] Initializing...");

#ifdef _UNIX
	int local_error = 0;
#endif

	// if hAppInstance is still == NULL it means that we havent been
	// reflectivly loaded so we must patch in the hAppInstance value
	// for use with loading server extensions later.
	InitAppInstance();

	srand( (unsigned int)time(NULL) );
	
	__try 
	{
		do
		{
			dprintf( "[SERVER] module loaded at 0x%08X", hAppInstance );
			
			// Open a THREAD item for the servers main thread, we use this to manage migration later.
			serverThread = thread_open();

			dprintf( "[SERVER] main server thread: handle=0x%08X id=0x%08X sigterm=0x%08X", serverThread->handle, serverThread->id, serverThread->sigterm );

			if( !(remote = remote_allocate(fd)) )
			{
				SetLastError( ERROR_NOT_ENOUGH_MEMORY );
				break;
			}

			remote->url = global_meterpreter_url;

			if (strcmp(global_meterpreter_transport+12, "TRANSPORT_SSL") == 0) {
				remote->transport = METERPRETER_TRANSPORT_SSL;
				dprintf("[SERVER] Using SSL transport...");
			} else if (strcmp(global_meterpreter_transport+12, "TRANSPORT_HTTPS") == 0) {
				remote->transport = METERPRETER_TRANSPORT_HTTPS;
				dprintf("[SERVER] Using HTTPS transport...");
			} else if (strcmp(global_meterpreter_transport+12, "TRANSPORT_HTTP") == 0) {
				remote->transport = METERPRETER_TRANSPORT_HTTP;
				dprintf("[SERVER] Using HTTP transport...");
			}

			// Do not allow the file descriptor to be inherited by child processes
			SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0);

			dprintf("[SERVER] Initializing tokens...");

			// Store our thread handle
			remote->hServerThread = serverThread->handle;

#ifdef _WIN32
			// Store our process token
			if (!OpenThreadToken(remote->hServerThread, TOKEN_ALL_ACCESS, TRUE, &remote->hServerToken))
				OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &remote->hServerToken);

			// Copy it to the thread token
			remote->hThreadToken = remote->hServerToken;

			// Save the initial session/station/desktop names...
			remote->dwOrigSessionId      = server_sessionid();
			remote->dwCurrentSessionId   = remote->dwOrigSessionId;
			GetUserObjectInformation( GetProcessWindowStation(), UOI_NAME, &cStationName, 256, NULL );
			remote->cpOrigStationName    = _strdup( cStationName );
			remote->cpCurrentStationName = _strdup( cStationName );
			GetUserObjectInformation( GetThreadDesktop( GetCurrentThreadId() ), UOI_NAME, &cDesktopName, 256, NULL );
			remote->cpOrigDesktopName    = _strdup( cDesktopName );
			remote->cpCurrentDesktopName = _strdup( cDesktopName );
#endif




			// Process our default SSL-over-TCP transport
			if (remote->transport == METERPRETER_TRANSPORT_SSL) {
				dprintf("[SERVER] Flushing the socket handle...");
				server_socket_flush( remote );
		
				dprintf("[SERVER] Initializing SSL...");
				if( !server_initialize_ssl( remote ) )
					break;

				dprintf("[SERVER] Negotiating SSL...");
				if( !server_negotiate_ssl( remote ) )
					break;

				dprintf("[SERVER] Registering dispatch routines...");
				register_dispatch_routines();

				dprintf("[SERVER] Entering the main server dispatch loop for transport %d...", remote->transport);
				server_dispatch( remote );
		
				dprintf("[SERVER] Deregistering dispatch routines...");
				deregister_dispatch_routines( remote );
			}

			if (remote->transport == METERPRETER_TRANSPORT_HTTP || remote->transport == METERPRETER_TRANSPORT_HTTPS) {
				dprintf("[SERVER] Registering dispatch routines...");
				register_dispatch_routines();
				
				dprintf("[SERVER] Entering the main server dispatch loop for transport %d...", remote->transport);
#ifdef _WIN32
				server_dispatch_http_wininet( remote );
#else
				// XXX: Handle non-windows HTTP transport
#endif 

				dprintf("[SERVER] Deregistering dispatch routines...");
				deregister_dispatch_routines( remote );
			}

		} while (0);

		if (remote->transport == METERPRETER_TRANSPORT_SSL) {
			dprintf("[SERVER] Closing down SSL...");
			server_destroy_ssl( remote );
		}

		if( remote )
			remote_deallocate( remote );

	} 
	__except( exceptionfilter(GetExceptionCode(), GetExceptionInformation()) )
	{
		dprintf("[SERVER] *** exception triggered!");

		thread_kill( serverThread );
	}

	dprintf("[SERVER] Finished.");
	return res;
}
/*!
 * @brief Setup and run the server. This is called from Init via the loader.
 * @param fd The original socket descriptor passed in from the stager, or a pointer to stageless extensions.
 * @return Meterpreter exit code (ignored by the caller).
 */
DWORD server_setup(MetsrvConfig* config)
{
	THREAD* serverThread = NULL;
	Remote* remote = NULL;
	char stationName[256] = { 0 };
	char desktopName[256] = { 0 };
	DWORD res = 0;

	dprintf("[SERVER] Initializing from configuration: 0x%p", config);
	dprintf("[SESSION] Comms Fd: %u", config->session.comms_fd);
	dprintf("[SESSION] Expiry: %u", config->session.expiry);

	dprintf("[SERVER] UUID: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
		config->session.uuid[0], config->session.uuid[1], config->session.uuid[2], config->session.uuid[3],
		config->session.uuid[4], config->session.uuid[5], config->session.uuid[6], config->session.uuid[7],
		config->session.uuid[8], config->session.uuid[9], config->session.uuid[10], config->session.uuid[11],
		config->session.uuid[12], config->session.uuid[13], config->session.uuid[14], config->session.uuid[15]);

	// if hAppInstance is still == NULL it means that we havent been
	// reflectivly loaded so we must patch in the hAppInstance value
	// for use with loading server extensions later.
	InitAppInstance();

	srand((unsigned int)time(NULL));

	__try
	{
		do
		{
			dprintf("[SERVER] module loaded at 0x%08X", hAppInstance);

			// Open a THREAD item for the servers main thread, we use this to manage migration later.
			serverThread = thread_open();

			dprintf("[SERVER] main server thread: handle=0x%08X id=0x%08X sigterm=0x%08X", serverThread->handle, serverThread->id, serverThread->sigterm);

			if (!(remote = remote_allocate()))
			{
				SetLastError(ERROR_NOT_ENOUGH_MEMORY);
				break;
			}

			setup_ssl_lib(&remote->ssl);

			remote->orig_config = config;
			remote->sess_expiry_time = config->session.expiry;
			remote->sess_start_time = current_unix_timestamp();
			remote->sess_expiry_end = remote->sess_start_time + config->session.expiry;

			dprintf("[DISPATCH] Session going for %u seconds from %u to %u", remote->sess_expiry_time, remote->sess_start_time, remote->sess_expiry_end);

			DWORD transportSize = 0;
			if (!create_transports(remote, config->transports, &transportSize))
			{
				// not good, bail out!
				SetLastError(ERROR_BAD_ARGUMENTS);
				break;
			}

			// the first transport should match the transport that we initially connected on.
			// If it's TCP comms, we need to wire that up.
			if (remote->transport->type == METERPRETER_TRANSPORT_SSL && config->session.comms_fd)
			{
				((TcpTransportContext*)remote->transport->ctx)->fd = (SOCKET)config->session.comms_fd;
			}

			// Set up the transport creation function pointer
			remote->trans_create = create_transport;
			// Set up the transport removal function pointer
			remote->trans_remove = remove_transport;
			// and the config creation pointer
			remote->config_create = config_create;

			// Store our thread handle
			remote->server_thread = serverThread->handle;

			dprintf("[SERVER] Registering dispatch routines...");
			register_dispatch_routines();

			// this has to be done after dispatch routine are registered
			load_stageless_extensions(remote, (MetsrvExtension*)((LPBYTE)config->transports + transportSize));

			// Store our process token
			if (!OpenThreadToken(remote->server_thread, TOKEN_ALL_ACCESS, TRUE, &remote->server_token))
			{
				OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &remote->server_token);
			}

			if (scheduler_initialize(remote) != ERROR_SUCCESS)
			{
				SetLastError(ERROR_BAD_ENVIRONMENT);
				break;
			}

			// Copy it to the thread token
			remote->thread_token = remote->server_token;

			// Save the initial session/station/desktop names...
			remote->orig_sess_id = server_sessionid();
			remote->curr_sess_id = remote->orig_sess_id;
			GetUserObjectInformation(GetProcessWindowStation(), UOI_NAME, &stationName, 256, NULL);
			remote->orig_station_name = _strdup(stationName);
			remote->curr_station_name = _strdup(stationName);
			GetUserObjectInformation(GetThreadDesktop(GetCurrentThreadId()), UOI_NAME, &desktopName, 256, NULL);
			remote->orig_desktop_name = _strdup(desktopName);
			remote->curr_desktop_name = _strdup(desktopName);

			remote->sess_start_time = current_unix_timestamp();

			// loop through the transports, reconnecting each time.
			while (remote->transport)
			{
				if (remote->transport->transport_init)
				{
					dprintf("[SERVER] attempting to initialise transport 0x%p", remote->transport);
					// Each transport has its own set of retry settings and each should honour
					// them individually.
					if (!remote->transport->transport_init(remote->transport))
					{
						dprintf("[SERVER] transport initialisation failed, moving to the next transport");
						remote->transport = remote->transport->next_transport;

						// when we have a list of transports, we'll iterate to the next one.
						continue;
					}
				}

				dprintf("[SERVER] Entering the main server dispatch loop for transport %x, context %x", remote->transport, remote->transport->ctx);
				DWORD dispatchResult = remote->transport->server_dispatch(remote, serverThread);

				dprintf("[DISPATCH] dispatch exited with result: %u", dispatchResult);
				if (remote->transport->transport_deinit)
				{
					dprintf("[DISPATCH] deinitialising transport");
					remote->transport->transport_deinit(remote->transport);
				}

				dprintf("[TRANS] resetting transport");
				if (remote->transport->transport_reset)
				{
					remote->transport->transport_reset(remote->transport, dispatchResult == ERROR_SUCCESS && remote->next_transport == NULL);
				}

				// If the transport mechanism failed, then we should loop until we're able to connect back again.
				if (dispatchResult == ERROR_SUCCESS)
				{
					dprintf("[DISPATCH] Server requested shutdown of dispatch");
					// But if it was successful, and this is a valid exit, then we should clean up and leave.
					if (remote->next_transport == NULL)
					{
						dprintf("[DISPATCH] No next transport specified, leaving");
						// we weren't asked to switch transports, so we exit.
						break;
					}

					// we need to change transports to the one we've been given. We will assume, for now,
					// that the transport has been created using the appropriate functions and that it is
					// part of the transport list.
					dprintf("[TRANS] Moving transport from 0x%p to 0x%p", remote->transport, remote->next_transport);
					remote->transport = remote->next_transport;
					remote->next_transport = NULL;

				}
				else
				{
					// move to the next one in the list
					dprintf("[TRANS] Moving transport from 0x%p to 0x%p", remote->transport, remote->transport->next_transport);
					remote->transport = remote->transport->next_transport;
				}

				// transport switching and failover both need to support the waiting functionality.
				if (remote->next_transport_wait > 0)
				{
					dprintf("[TRANS] Sleeping for %u seconds ...", remote->next_transport_wait);

					sleep(remote->next_transport_wait);

					// the wait is a once-off thing, needs to be reset each time
					remote->next_transport_wait = 0;
				}
			}

			// clean up the transports
			while (remote->transport)
			{
				remove_transport(remote, remote->transport);
			}

			dprintf("[SERVER] Deregistering dispatch routines...");
			deregister_dispatch_routines(remote);
		} while (0);

		dprintf("[DISPATCH] calling scheduler_destroy...");
		scheduler_destroy();

		dprintf("[DISPATCH] calling command_join_threads...");
		command_join_threads();

		remote_deallocate(remote);
	}
	__except (exceptionfilter(GetExceptionCode(), GetExceptionInformation()))
	{
		dprintf("[SERVER] *** exception triggered!");

		thread_kill(serverThread);
	}

	dprintf("[SERVER] Finished.");
	return res;
}
Beispiel #12
0
void kcall(struct thread *image) {

	if (image->flags & TF_USER) {
		// perform syscall

		// save user state
		image->usr_eip = image->eip;
		image->usr_esp = image->useresp;

		// switch to system mode
		image->ss = 0x21;
		image->ds = 0x21;
		image->cs = 0x19;
		image->flags &= ~TF_USER;

		// restore system state
		image->eip = image->sys_eip;
		image->useresp = image->sys_esp;		

		return;
	}

	switch (image->eax) {

	case KCALL_SPAWN: {

		int id = thread_new();
		if (id == -1) {
			// failure to create new thread
			image->eax = -1;
			break;
		}

		struct thread *thread = thread_get(id);
		struct t_info *state = (void*) image->ebx;

		// initialize thread state
		thread->useresp = state->regs.esp;
		thread->esp     = (uintptr_t) &thread->num;
		thread->ss      = 0x21;
		thread->ds      = 0x21;
		thread->cs      = 0x19;
		thread->eflags  = image->eflags;
		thread->eip     = state->regs.eip;
		thread->ebp     = state->regs.ebp;
		thread->esi     = state->regs.esi;
		thread->edi     = state->regs.edi;
		thread->edx     = state->regs.edx;
		thread->ecx     = state->regs.ecx;
		thread->ebx     = state->regs.ebx;
		thread->eax     = state->regs.eax;

		// add to scheduler queue
		thread->state = TS_QUEUED;
		schedule_push(thread);

		image->eax = id;
		break;
	}

	case KCALL_REAP: {

		struct thread *target = thread_get(image->ebx);

		if (target->state != TS_PAUSED) {
			image->eax = TE_STATE;
		}
		else {

			if (image->ecx) {
				save_info((void*) image->ecx, target);
			}

			image->eax = 0;
			thread_kill(target);
		}

		break;
	}

	case KCALL_GETTID: {

		image->eax = image->id;

		break;
	}

	case KCALL_YIELD: {
		
		thread_save(image);
		schedule_push(image);
		image->state = TS_QUEUED;

		break;
	}

	case KCALL_PAUSE: {

		struct thread *target = thread_get(image->ebx);
		if (image->ebx == (uint32_t) -1) target = image;

		if (!target) {
			image->eax = TE_EXIST;
		}
		else switch (target->state) {
		case TS_RUNNING:

			// pause (normal, from running)
			thread_save(target);
			target->state = TS_PAUSED;
			
			image->eax = 0;
			break;

		case TS_QUEUED:

			// pause (normal, from queued)
			schedule_remv(target);
			target->state = TS_PAUSED;

			image->eax = 0;
			break;

		case TS_WAITING:

			// pause (waiting)
			event_remv(target->id, target->event);
			target->state = TS_PAUSEDW;

			image->eax = 0;
			break;

		default:

			// invalid state transition
			image->eax = TE_STATE;
			break;
		}

		break;
	}

	case KCALL_RESUME: {

		struct thread *target = thread_get(image->ebx);
		if (!target) {
			image->eax = TE_EXIST;
		}
		else switch (target->state) {
		case TS_PAUSED:

			// resume thread by scheduling
			schedule_push(target);
			target->state = TS_QUEUED;

			image->eax = 0;
			break;

		case TS_PAUSEDW:

			// resume thread by entering wait queue
			event_wait(target->id, target->event);
			target->state = TS_WAITING;

			image->eax = 0;
			break;

		default:

			image->eax = TE_STATE;
			break;
		}

		break;
	}

	case KCALL_GETSTATE: {

		struct thread *target = thread_get(image->ebx);
		if (image->ebx == (uint32_t) -1) target = image;

		if (!target) {
			image->eax = TE_EXIST;
		}
		else if (target->state != TS_PAUSED && target->state != TS_PAUSEDW && target != image) {
			image->eax = TE_STATE;
		}
		else {
			save_info((void*) image->ecx, target);
			image->eax = 0;
		}
		
		break;
	}

	case KCALL_SETSTATE: {

		struct thread *target = thread_get(image->ebx);
		if (image->ebx == (uint32_t) -1) target = image;

		if (!target) {
			image->eax = TE_EXIST;
		}
		else switch (target->state) {
		case TS_PAUSED:
		case TS_PAUSEDW:
		case TS_RUNNING: {

			struct t_info *src = (void*) image->ecx;

			if (src->flags & TF_DEAD) {

				// kill thread
				if (target->state == TS_RUNNING) {
					thread_save(target);
					target->state = TS_PAUSED;
				}

				// notify reaper
				dead_push(target);
			}

			if (target->pctx != src->pctx) {

				// change paging contexts
				pctx_load(src->pctx);
			}

			// save thread state
			target->pctx  = src->pctx;
			target->flags = src->flags;
			target->fault = src->fault;

			if (target->state != TS_RUNNING) {

				// save register state
				target->edi = src->regs.edi;
				target->esi = src->regs.esi;
				target->ebp = src->regs.ebp;
				target->useresp = src->regs.esp;
				target->ebx = src->regs.ebx;
				target->edx = src->regs.edx;
				target->ecx = src->regs.ecx;
				target->eax = src->regs.eax;
				target->eip = src->regs.eip;
				target->eflags = src->regs.eflags;

				// save MMX/SSE state
				if (!target->fxdata) target->fxdata = heap_alloc(512);
				memcpy(target->fxdata, &src->regs.fxdata[0], 512);
			}

			target->usr_eip = src->usr_ip;
			target->usr_esp = src->usr_sp;

			image->eax = 0;
			break;
		}

		default:

			image->eax = TE_STATE;
			break;
		}

		break;
	}

	case KCALL_GETDEAD: {

		if (dead_peek()) {
			struct thread *dead = dead_pull();
			image->eax = dead->id;
		}
		else {
			thread_save(image);
			image->state = TS_PAUSED;

			dead_wait(image);
		}

		break;
	}

	case KCALL_GETFAULT: {

		if (fault_peek()) {
			struct thread *fault = fault_pull();
			image->eax = fault->id;
		}
		else {
			thread_save(image);
			image->state = TS_PAUSED;

			fault_wait(image);
		}

		break;
	}

	case KCALL_WAIT: {
		
		image->eax = event_wait(image->id, image->ebx);

		break;

	}

	case KCALL_RESET: {

		if (image->ebx < 240) {
			extern int irqstate[EV_COUNT];

			irqstate[image->ebx] = 0;
			irq_unmask(image->ebx);
		}

		image->eax = 0;

		break;
	}

	case KCALL_SYSRET: {

		// save system state
		image->sys_eip = image->eip;
		image->sys_esp = image->useresp;
		
		// perform return value swap-in
		image->eax = image->ebp;

		// switch to usermode
		image->ss = 0x33;
		image->ds = 0x33;
		image->cs = 0x2B;
		image->flags |= TF_USER;

		// restore user state
		image->eip = image->usr_eip;
		image->useresp = image->usr_esp;

		break;
	}

	case KCALL_NEWPCTX: {

		image->eax = pctx_new();

		break;
	}

	case KCALL_FREEPCTX: {

		image->eax = pctx_free(image->ebx);

		break;
	}


	case KCALL_SETFRAME: {

		page_set(image->ebx, page_fmt(image->ecx, page_get(image->ebx)));
		image->eax = 0;

		break;
	}

	case KCALL_SETFLAGS: {

		page_set(image->ebx, page_fmt(page_ufmt(page_get(image->ebx)), image->ecx));
		image->eax = 0;

		break;
	}

	case KCALL_GETFRAME: {

		uint32_t off  = image->ebx & 0xFFF;
		uint32_t page = image->ebx & ~0xFFF;
		image->eax = page_ufmt(page_get(page)) | off;

		break;
	}

	case KCALL_GETFLAGS: {

		image->eax = page_get(image->ebx) & PF_MASK;

		break;
	}

	case KCALL_NEWFRAME: {

		uint64_t frame = frame_new();
		image->eax = frame & 0xFFFFFFFF;
		image->ebx = frame >> 32ULL;

		break;
	}

	case KCALL_FREEFRAME: {

		frame_free(image->ebx);

		image->eax = 0;
		break;
	}

	case KCALL_TAKEFRAME: {
		
		image->eax = 1;
		break;
	}	

	default: {

		debug_printf("warning: unimplemented kcall %d\n", image->eax);
		image->eax = -1;

		break;
	}

	}
}
Beispiel #13
0
void sig_norestart_condwait(void)
{
	unsigned long long start;
	mutex_t mutex;
	cond_t cond;
	struct cond_mutex cm = {
		.mutex = &mutex,
		.cond = &cond,
		.tid = thread_self(),
	};
	thread_t cond_killer_tid;
	struct sigaction sa = {
		.sa_handler = sighandler,
		.sa_flags = 0,
	};
	sigemptyset(&sa.sa_mask);

	fprintf(stderr, "%s\n", __FUNCTION__);

	check_unix("sigaction", sigaction(SIGRTMIN, &sa, NULL), 0);
	check("mutex_init", mutex_init(&mutex, PTHREAD_MUTEX_DEFAULT, 0), 0);
	check("cond_init", cond_init(&cond, 0), 0);
	check("mutex_lock", mutex_lock(&mutex), 0);
	check("thread_spawn",
	      thread_spawn(&cond_killer_tid, 2, cond_killer, &cm), 0);
	thread_msleep(11);

	start = rt_timer_tsc();
	sig_seen = 0;
#ifdef XENO_POSIX
	check("cond_wait", cond_wait(&cond, &mutex, XN_INFINITE), 0);
#else /* native */
	{
		int err = cond_wait(&cond, &mutex, XN_INFINITE);
		if (err == 0)
			err = -EINTR;
		check("cond_wait", err, -EINTR);
	}
#endif /* native */
	check_sleep("cond_wait", start);
	check("sig_seen", sig_seen, 1);
	check("mutex_unlock", mutex_unlock(&mutex), 0);
	check("thread_join", thread_join(cond_killer_tid), 0);
	check("mutex_destroy", mutex_destroy(&mutex), 0);
	check("cond_destroy", cond_destroy(&cond), 0);
}

void sig_restart_condwait(void)
{
	unsigned long long start;
	mutex_t mutex;
	cond_t cond;
	struct cond_mutex cm = {
		.mutex = &mutex,
		.cond = &cond,
		.tid = thread_self(),
	};
	thread_t cond_killer_tid;
	struct sigaction sa = {
		.sa_handler = sighandler,
		.sa_flags = 0,
	};
	sigemptyset(&sa.sa_mask);

	fprintf(stderr, "%s\n", __FUNCTION__);

	check_unix("sigaction", sigaction(SIGRTMIN, &sa, NULL), 0);
	check("mutex_init", mutex_init(&mutex, PTHREAD_MUTEX_DEFAULT, 0), 0);
	check("cond_init", cond_init(&cond, 0), 0);
	check("mutex_lock", mutex_lock(&mutex), 0);
	check("thread_spawn",
	      thread_spawn(&cond_killer_tid, 2, cond_killer, &cm), 0);
	thread_msleep(11);

	start = rt_timer_tsc();
	sig_seen = 0;
#ifdef XENO_POSIX
	check("cond_wait", cond_wait(&cond, &mutex, XN_INFINITE), 0);
#else /* native */
	{
		int err = cond_wait(&cond, &mutex, XN_INFINITE);
		if (err == 0)
			err = -EINTR;
		check("cond_wait", err, -EINTR);
	}
#endif /* native */
	check_sleep("cond_wait", start);
	check("sig_seen", sig_seen, 1);
	check("mutex_unlock", mutex_unlock(&mutex), 0);
	check("thread_join", thread_join(cond_killer_tid), 0);
	check("mutex_destroy", mutex_destroy(&mutex), 0);
	check("cond_destroy", cond_destroy(&cond), 0);
}

void *mutex_killer(void *cookie)
{
	unsigned long long start;
	struct cond_mutex *cm = cookie;

	start = rt_timer_tsc();
	check("mutex_lock", mutex_lock(cm->mutex), 0);
	check_sleep("mutex_lock", start);
	check("cond_signal", cond_signal(cm->cond), 0);
	thread_msleep(10);
	check("thread_kill", thread_kill(cm->tid, SIGRTMIN), 0);
	check("mutex_unlock", mutex_unlock(cm->mutex), 0);

	return NULL;
}
Beispiel #14
0
void thread1(void* info) 
{
  status(1,5);
  thread_kill(thread_self());
  fprintf(stderr, "** error: killed thread is executing\n");
}
Beispiel #15
0
/*
 * I/O timeout in seconds
 */
int IO_TIMEOUT = (10*60);

#include "proc.h"
typedef struct {
	int	t_x;
	int	t_pid;
	double	t_Time;
	int	t_id;
	int	t_fd;
	int	t_timer;
	int	t_sig;
 void (*t_pipe)(int sig);
	int	t_sser;
	int	t_cln;
 sigjmp_buf	t_ioenv;
} ThreadIO;
static int sser[MAX_THREADS]; /* setjmp serial */
static int nsig[MAX_THREADS];
static int threadPID[MAX_THREADS];
static ThreadIO *threadIO[MAX_THREADS];

void clearThreadFilter();
void clearThreadEnv(){
	int ti;

	for( ti = 0; ti < MAX_THREADS; ti++ ){
		if( threadIO[ti] ){
			sv1log("-- clearThreadEnv[%d] %X %d %d %d\n",
				ti,p2i(threadIO[ti]),sser[ti],nsig[ti],threadPID[ti]);
		}
		threadIO[ti] = 0;
		sser[ti] = 0;
		nsig[ti] = 0;
		threadPID[ti] = 0;
	}
	clearThreadFilter();
}
void clearThreadSig(){
	int ti;
	for( ti = 0; ti < MAX_THREADS; ti++ ){
		if( nsig[ti] ){
			sv1log("-- clearThreadSig[%d] %d %d\n",ti,
				nsig[ti],sser[ti]);
		}
		nsig[ti] = 0;
	}
}

int getmtpid();
static int okenv(ThreadIO *tio){
	int off = (char*)tio - (char*)&tio;
	if( tio->t_x < 0 || elnumof(threadIO) <= tio->t_x ){
		porting_dbg("--stale ThreadIO %X %X x=%X",p2i(tio),off,tio->t_x);
		return 0;
	}
	if( tio->t_sser != sser[tio->t_x] ){
		porting_dbg("--stale ThreadIO %X %X ser=%X/%X",p2i(tio),off,
			tio->t_sser,sser[tio->t_x]);
		return 0;
	}
	if( tio->t_pid != getmtpid() ){
		porting_dbg("--stale ThreadIO %X %X pid=%d/%d tid=%X",p2i(tio),off,
			tio->t_pid,getmtpid(),tio->t_id
		);
		return 0;
	}
	return 1;
}

int gotSIGPIPE(){
	return nsig[getthreadix()];
}
int iamServer();
int MAX_SIGPIPE = 100; /* max. SIGPIPE caught in an output action */
static void io_timeout(int sig){
	ThreadIO *myenv;
	ThreadIO *ev1;
	int mx,my_tid,tid,tid1;
	int tn,tx,ti;
	int my_pid;

	Vsignal(SIGPIPE,io_timeout); /*should be before thread_kill()*/
	if( sig == SIGPIPE ){
		/* should not do longjump() to set ferror()...
		 * and maybe the longjump() on SIGPIPE is not necessaly.
		 * 9.8.2 set explicitly by Setferror() as an workaround
		 */
		if( lNOSIGPIPE() ){
			return;
		}
	}

	mx = getthreadix();
	my_tid = getthreadid();
	myenv = threadIO[mx];
	sv1log("IO_TIMEOUT[%d] SIGPIPE got by[%X] longjump %X[%X] %d/%d\n",
		mx,my_tid,p2i(myenv),myenv?myenv->t_id:0,
		actthreads(),numthreads());
	if( numthreads() ){
		if( isatty(fileno(stderr)) )
		fprintf(stderr,"-- %X gotSIGPIPE(%d) [%d]%X[%X] %d/%d\n",
			TID,sig,mx,p2i(myenv),myenv?myenv->t_id:0,
			actthreads(),numthreads());
	}

	if( myenv && myenv->t_id == my_tid && okenv(myenv) ){
		nsig[mx] += 1;
		if( myenv->t_sig != 0 ){
			sv1log("IO_TIMEOUT[%d] SIG*%d (%d %d) in longjump\n",
				mx,nsig[mx],myenv->t_sig,sig);
			if( MAX_SIGPIPE < nsig[mx] )
			if( !lSINGLEP() && !iamServer() ){
				sv1log("####Finish: Too Many SIGPIPE: %d\n",
					nsig[mx]);
				Finish(-1);
			}
			return;
		}
		myenv->t_sig = sig;
		siglongjmpX(myenv->t_ioenv,sig);
		return;
	}

	tid = 0;
	my_pid = getmtpid();
	for( tn = 0; tn < elnumof(threadIO); tn++ ){
		tx = (mx + 1 + tn) % elnumof(threadIO);
		if( threadPID[tx] != my_pid ){
			threadIO[tx] = 0;
			continue;
		}
		if( (ev1 = threadIO[tx]) == 0 /*|| !validenv(tx,ev1) */ ){
			continue;
		}
		if( !okenv(ev1) ){
			threadIO[tx] = 0;
			continue;
		}
		if( (tid1 = ev1->t_id) == 0 )
			continue;
		sv1log("IO_TIMEOUT[%d] candidate %X [%d]\n",
			tx,tid1,ev1->t_fd);
		if( tid == 0 ){
			tid = tid1;
		}
		porting_dbg("candidate handler IO_TIMEOUT[%d] %X [%d]",
			tx,tid,ev1->t_fd);
		nsig[tx] += 1;
		break;
	}
	if( tid == my_tid ){
		sv1log("IO_TIMEOUT: dangling? SIG%d -> %X\n",sig,my_tid);
		porting_dbg("IO_TIMEOUT: dangling? SIG%d -> %X ++++",
			sig,my_tid);
	}else
	if( tid ){
		porting_dbg("IO_TIMEOUT: forwarded SIG%d %X -> %X",
			sig,my_tid,tid);
		sv1log("IO_TIMEOUT: forwarded SIG%d %X -> %X\n",
			sig,my_tid,tid);
		thread_kill(tid,sig);
	}else{
		sv1log("IO_TIMEOUT: dangling SIG%d -> %X\n",sig,my_tid);
		porting_dbg("IO_TIMEOUT: dangling SIG%d -> %X ----",
			sig,my_tid);
	}

}