示例#1
0
/*
 * MemoryWrite, StackWrite
 * If store occurs and that address was used for read, make a log
 */
VOID MemoryWrite(ADDRINT memaddr, ADDRINT writesize)
{
	treeNode *node;

	ADDRINT startoffset, endoffset;

	PIN_RWMutexReadLock(&data_lock);
	node = FindAddressInRange(data_root, memaddr);
	PIN_RWMutexUnlock(&data_lock);
	if(node && node->usedforread == TRUE)
	{
		startoffset = memaddr - node->address + node->offset;
		endoffset = memaddr - node->address + node->offset + writesize;

		fprintf(trace, "%x%lx:%s:%lx:%lx:D\n", pid, node->readid, node->path, startoffset, endoffset);
		fflush(trace);
		return;
	}
	PIN_RWMutexReadLock(&malloc_lock);
	node = FindAddressInRange(malloc_root, memaddr);
	PIN_RWMutexUnlock(&malloc_lock);
	if(node && node->usedforread == TRUE)
	{
		startoffset = memaddr - node->address + node->offset;
		endoffset = memaddr - node->address + node->offset + writesize;

		fprintf(trace, "%x%lx:%s:%lx:%lx:M\n", pid, node->readid, node->path, startoffset, endoffset);
		fflush(trace);
		return;
	}
}
示例#2
0
static void DoTestReaderStress(THREAD_INFO *info, UINT32 *done)
{
    // This test just tries to acquire and release PIN_RWMUTEX as fast as possible
    // as a reader lock.

    PIN_RWMutexReadLock(&RWMutex);
    PIN_RWMutexUnlock(&RWMutex);
    CheckIfDone(info, done);
}
示例#3
0
/*
 * Return
 * Called when native procedure returns
 * Delete read info of removed stack area
 */
VOID Return(ADDRINT sp)
{
	PIN_THREAD_UID threadid = PIN_ThreadUid();
	PIN_RWMutexReadLock(&thread_lock);
	THREAD* thread = FindThread(threadid);
	PIN_RWMutexUnlock(&thread_lock);
	treeNode *node = FindMinAddress(thread->stack);
	if(node == NULL)
		return;
	while(node->address <= sp)
	{
		thread->stack = DeleteAddress(thread->stack, node->address);
		node = FindMinAddress(thread->stack);
		if(node == NULL)
			return;
	}
}
示例#4
0
VOID StackWrite(ADDRINT memaddr, ADDRINT writesize)
{
	treeNode *node;
	PIN_THREAD_UID threadid = PIN_ThreadUid();
	ADDRINT startoffset, endoffset;

	PIN_RWMutexReadLock(&thread_lock);
	THREAD* thread = FindThread(threadid);
	PIN_RWMutexUnlock(&thread_lock);

	node = FindAddressInRange(thread->stack, memaddr);
	if(node && node->usedforread == TRUE)
	{
		startoffset = memaddr - node->address + node->offset;
		endoffset = memaddr - node->address + node->offset + writesize;

		fprintf(trace, "%x%lx:%s:%lx:%lx:S\n", pid, node->readid, node->path, startoffset, endoffset);
		fflush(trace);
	}
}
示例#5
0
static void DoTestReaderWriterIntegrity(THREAD_INFO *info, UINT32 *done)
{
    // This test checks that a "writer" thread can never hold the lock while
    // there is an active reader.

    if (info->_workerId & 1)
    {
        // Reader thread.
        //
        PIN_RWMutexReadLock(&RWMutex);
        ATOMIC::OPS::Increment(&ActiveReaders, 1);
        if (ATOMIC::OPS::Load(&IsActiveWriter))
        {
            std::cout << "Reader got lock while there is an active writer" << std::endl;
            PIN_ExitProcess(1);
        }

        ATOMIC::OPS::Delay(DELAY_COUNT);

        ATOMIC::OPS::Increment(&ActiveReaders, -1);
        PIN_RWMutexUnlock(&RWMutex);
    }
    else
    {
        // Writer thread.
        //
        PIN_RWMutexWriteLock(&RWMutex);
        ATOMIC::OPS::Store<BOOL>(&IsActiveWriter, TRUE);
        if (ATOMIC::OPS::Load(&ActiveReaders) != 0)
        {
            std::cout << "Writer has lock while there are active readers" << std::endl;
            PIN_ExitProcess(1);
        }

        ATOMIC::OPS::Delay(DELAY_COUNT);

        ATOMIC::OPS::Store<BOOL>(&IsActiveWriter, FALSE);
        PIN_RWMutexUnlock(&RWMutex);
    }
    CheckIfDone(info, done);
}
示例#6
0
static void DoTestReaderWriterStress(THREAD_INFO *info, UINT32 *done)
{
    // This test uses a mix of "reader" and "writer" threads to acquire and
    // release the PIN_RWMUTEX as fast as possible.

    if (info->_workerId & 1)
    {
        // Reader thread.
        //
        PIN_RWMutexReadLock(&RWMutex);
        PIN_RWMutexUnlock(&RWMutex);
    }
    else
    {
        // Writer thread.
        //
        PIN_RWMutexWriteLock(&RWMutex);
        PIN_RWMutexUnlock(&RWMutex);
    }
    CheckIfDone(info, done);
}
示例#7
0
/*
 * SysBefore
 * Our focus is on "read" syscall, so it traces only read-like syscalls - read, readv, pread, preadv
 */
VOID SysBefore(ADDRINT ip, ADDRINT num, ADDRINT arg0, ADDRINT arg1, ADDRINT arg2, ADDRINT arg3, ADDRINT arg4, ADDRINT arg5, ADDRINT sp)
{

	treeNode *node;
	struct stat stat;
	off_t offset;
	char buf[2][MAX_BUFSIZE];
	int tmp;
	int i;
	long unsigned int readid;
	long unsigned int size;
	struct iovec *vec;

	PIN_THREAD_UID threadid = PIN_ThreadUid();
	PIN_RWMutexReadLock(&thread_lock);
	THREAD* thread = FindThread(threadid);
	PIN_RWMutexUnlock(&thread_lock);
	assert(thread);

	switch(num)
	{
	case SYS_READ:
	case SYS_PREAD64:
		//arg0 : fd
		//arg1 : buf addr
		//arg2 : buf size

		//stdin
		if(arg0 == 0)
			break;

		//Get the path of current file
		sprintf(buf[0], "/proc/self/fd/%d", (int)arg0);
		tmp = readlink(buf[0], buf[1], MAX_BUFSIZE);

		//Skip socket, pipe, proc filesystem, etc
		if(buf[1][0] != '/')
			break;

		if(strncmp(buf[1], "/proc", 5) == 0)
			break;
		else if(strncmp(buf[1], "/dev/urandom", 12)== 0)
			break;

		buf[1][tmp] = '\0';

		if(num == SYS_READ)
		{
			//If SYS_READ, we have to find out current file pointer
			offset = lseek((int)arg0, 0, SEEK_CUR);
			if(offset+1 == 0)
				offset = 0;
		}
		else
		{
			//Or pread case, file pointer is given
			offset = arg3;
		}

		//Get the file size
		size = fstat((int)arg0, &stat);
		assert(size == 0);

		size = stat.st_size;
		if(offset+arg2 > size)
			size = size - offset;
		else
			size = arg2;
		if(size <= 0)
			break;

		//Get Unique ID for each Read
		readid = GetReadId();

		sprintf(thread->buffer, "%s:%lx:%lx:%lx:", buf[1], offset, size, stat.st_size);

		/*
		 * Add Read Info to Data Structure
		 *
		 * Find the buffer address in malloc BST
		 * 	if found, write the info to it
		 *  else
		 *  	Buffer is in stack or data segment
		 */
		PIN_RWMutexReadLock(&malloc_lock);
		node = FindAddressInRange(malloc_root, arg1);
		PIN_RWMutexUnlock(&malloc_lock);
		if(node != NULL)
		{
			node->usedforread = TRUE;
			node->offset = offset;
			node->fd = (int)arg0;
			if(node->path != NULL)
				free(node->path);
			node->path = strdup(buf[1]);
			node->size = size;
			node->readid = readid;
			strcat(thread->buffer, "M");
		}
		else if(arg1 >= sp - pagesize)
		{
			thread->stack = InsertSAddress(thread->stack, arg1, (int)arg0, size, offset, buf[1], readid);
			strcat(thread->buffer, "S");
		}
		else
		{
			PIN_RWMutexWriteLock(&data_lock);
			data_root = InsertDAddress(data_root, arg1, (int)arg0, size, offset, buf[1], readid);
			PIN_RWMutexUnlock(&data_lock);
			strcat(thread->buffer, "D");
		}
		fprintf(trace, "%s\n", thread->buffer);
		fflush(trace);
		break;

	case SYS_PREADV:
	case SYS_READV:
		//arg0 : fd
		//arg1 : iov
		//arg2 : iovcnt
		//iovec.iov_base : address
		//iovec.iov_len : length

		//stdin
		if(arg0 == 0)
			break;

		sprintf(buf[0], "/proc/self/fd/%d", (int)arg0);
		tmp = readlink(buf[0], buf[1], MAX_BUFSIZE);
		if(buf[1][0] != '/')
			break;

		if(strncmp(buf[1], "/proc", 5) == 0)
			break;

		readid = GetReadId();
		buf[1][tmp] = '\0';

		if(num == SYS_READV)
		{
			offset = lseek((int)arg0, 0, SEEK_CUR);
			if(offset+1 == 0)
				offset = 0;
		}
		else
			offset = arg3;

		size = fstat((int)arg0, &stat);
		assert(size == 0);


		vec = (struct iovec *)arg1;
		for(i=0; i < (int)arg2; i++)
		{
			size = stat.st_size;
			if(offset+vec[i].iov_len > size)
				size = size - offset;
			else
				size = vec[i].iov_len;

			if(size <= 0)
				continue;

			PIN_RWMutexReadLock(&malloc_lock);
			node = FindAddressInRange(malloc_root, (ADDRINT)vec[i].iov_base);
			PIN_RWMutexUnlock(&malloc_lock);
			sprintf(thread->buffer, "%s:%lx:%lx:%lx:",buf[1], offset, size, stat.st_size);

			if(node != NULL)
			{
				strcat(thread->buffer, "M");
				node->usedforread = TRUE;
				node->offset = offset;
				node->fd = (int)arg0;
				if(node->path != NULL)
					free(node->path);
				node->path = strdup(buf[1]);
				node->size = size;
				node->readid = readid;
			}
			else if(arg1 >= sp - pagesize)
			{
				strcat(thread->buffer, "S");
				thread->stack = InsertSAddress(thread->stack, arg1, (int)arg0, size, offset, buf[1], readid);
			}
			else
			{
				strcat(thread->buffer, "D");
				PIN_RWMutexWriteLock(&data_lock);
				data_root = InsertDAddress(data_root, arg1, (int)arg0, size, offset, buf[1], readid);
				PIN_RWMutexUnlock(&data_lock);
			}
			fprintf(trace, "%s\n", thread->buffer);
			fflush(trace);
		}
		break;

		/*
	case SYS_WRITE:
	case SYS_PWRITE64:
		if(arg0 == 1 || arg0 == 2)
			break;

		if(num == SYS_WRITE)
		{
			offset = lseek((int)arg0, 0, SEEK_CUR);
			if(offset + 1 == 0)
				offset = 0;
		}
		else
			offset = arg3;

		sprintf(thread->buffer, "%lx:%lx:%lx:%lx:%lx:", num, arg0, arg1, arg2, offset);
		break;

	case SYS_PWRITEV:
	case SYS_WRITEV:
		//stdin
		if(arg0 == 0)
			break;

		sprintf(buf[0], "/proc/self/fd/%d", (int)arg0);
		tmp = readlink(buf[0], buf[1], MAX_BUFSIZE);
		buf[1][tmp] = '\0';

		if(num == SYS_PWRITEV)
		{
			offset = lseek((int)arg0, 0, SEEK_CUR);
			if(offset + 1 == 0)
				offset = 0;
		}
		else
			offset = arg3;

		vec = (struct iovec *)arg1;
		for(i=0; i < (int)arg2; i++)
		{
			sprintf(thread->buffer, "%lx:%lx:%lx:%lx:%lx:", num, arg0, (ADDRINT)vec[i].iov_base, vec[i].iov_len, offset);
		}
		break;
		*/

	default :
		break;
	}
}