Пример #1
0
void*
egg_secure_alloc_full (const char *tag,
                       size_t length,
                       int flags)
{
	Block *block;
	void *memory = NULL;

	if (tag == NULL)
		tag = "?";

	if (length > 0xFFFFFFFF / 2) {
		if (egg_secure_warnings)
			fprintf (stderr, "tried to allocate an insane amount of memory: %lu\n", 
			         (unsigned long)length);   
		return NULL;
	}

	/* Can't allocate zero bytes */
	if (length == 0)
		return NULL;
	
	DO_LOCK ();
	
		for (block = all_blocks; block; block = block->next) {
			memory = sec_alloc (block, tag, length);
			if (memory)
				break;	
		}
	
		/* None of the current blocks have space, allocate new */
		if (!memory) {
			block = sec_block_create (length, tag);
			if (block)
				memory = sec_alloc (block, tag, length);
		}
		
#ifdef WITH_VALGRIND
		if (memory != NULL)
			VALGRIND_MALLOCLIKE_BLOCK (memory, length, sizeof (void*), 1);
#endif
	
	DO_UNLOCK ();

	if (!memory && (flags & EGG_SECURE_USE_FALLBACK)) {
		memory = egg_memory_fallback (NULL, length);
		if (memory) /* Our returned memory is always zeroed */
			memset (memory, 0, length);
	}
	
	if (!memory)
		errno = ENOMEM;
	
	return memory;
}
Пример #2
0
void
egg_secure_free_full (void *memory, int flags)
{
	Block *block = NULL;

	if (memory == NULL)
		return;

	DO_LOCK ();

		/* Find out where it belongs to */
		for (block = all_blocks; block; block = block->next) {
			if (sec_is_valid_word (block, memory))
				break;
		}

#ifdef WITH_VALGRIND
		/* We like valgrind's warnings, so give it a first whack at checking for errors */
		if (block != NULL || !(flags & GKR_SECURE_USE_FALLBACK))
			VALGRIND_FREELIKE_BLOCK (memory, sizeof (word_t));
#endif

		if (block != NULL) {
			sec_free (block, memory);
			if (block->used == 0)
				sec_block_destroy (block);
		}

	DO_UNLOCK ();

	if (!block) {
		if ((flags & GKR_SECURE_USE_FALLBACK)) {
			egg_memory_fallback (memory, 0);
		} else {
			if (egg_secure_warnings)
				fprintf (stderr, "memory does not belong to mate-keyring: 0x%08lx\n",
				         (unsigned long)memory);
			ASSERT (0 && "memory does does not belong to mate-keyring");
		}
	}
}
Пример #3
0
void*
egg_secure_realloc_full (void *memory, size_t length, int flags)
{
	Block *block = NULL;
	size_t previous = 0;
	int donew = 0;
	void *alloc = NULL;

	if (length > 0xFFFFFFFF / 2) {
		if (egg_secure_warnings)
			fprintf (stderr, "tried to allocate an insane amount of memory: %lu\n",
			         (unsigned long)length);
		return NULL;
	}

	if (memory == NULL)
		return egg_secure_alloc_full (length, flags);
	if (!length) {
		egg_secure_free_full (memory, flags);
		return NULL;
	}

	DO_LOCK ();

		/* Find out where it belongs to */
		for (block = all_blocks; block; block = block->next) {
			if (sec_is_valid_word (block, memory)) {
				previous = sec_allocated (block, memory);

#ifdef WITH_VALGRIND
				/* Let valgrind think we are unallocating so that it'll validate */
				VALGRIND_FREELIKE_BLOCK (memory, sizeof (word_t));
#endif

				alloc = sec_realloc (block, memory, length);

#ifdef WITH_VALGRIND
				/* Now tell valgrind about either the new block or old one */
				VALGRIND_MALLOCLIKE_BLOCK (alloc ? alloc : memory,
				                           alloc ? length : previous,
				                           sizeof (word_t), 1);
#endif
				break;
			}
		}

		/* If it didn't work we may need to allocate a new block */
		if (block && !alloc)
			donew = 1;

		if (block && block->used == 0)
			sec_block_destroy (block);

	DO_UNLOCK ();

	if (!block) {
		if ((flags & GKR_SECURE_USE_FALLBACK)) {
			/*
			 * In this case we can't zero the returned memory,
			 * because we don't know what the block size was.
			 */
			return egg_memory_fallback (memory, length);
		} else {
			if (egg_secure_warnings)
				fprintf (stderr, "memory does not belong to mate-keyring: 0x%08lx\n",
				         (unsigned long)memory);
			ASSERT (0 && "memory does does not belong to mate-keyring");
			return NULL;
		}
	}

	if (donew) {
		alloc = egg_secure_alloc_full (length, flags);
		if (alloc) {
			memcpy (alloc, memory, previous);
			egg_secure_free_full (memory, flags);
		}
	}

	if (!alloc)
		errno = ENOMEM;

	return alloc;
}