/** * mate_keyring_memory_alloc: * @sz: The new desired size of the memory block. * * Allocate a block of mate-keyring non-pageable memory. * * If non-pageable memory cannot be allocated then normal memory will be * returned. * * Return value: The new memory block which should be freed with * mate_keyring_memory_free() **/ gpointer mate_keyring_memory_alloc (gulong sz) { gpointer p; /* Try to allocate secure memory */ p = egg_secure_alloc_full (sz, GKR_SECURE_USE_FALLBACK); /* Our fallback will always allocate */ g_assert (p); return p; }
char* egg_secure_strdup_full (const char *tag, const char *str, int options) { size_t len; char *res; if (!str) return NULL; len = strlen (str) + 1; res = (char *)egg_secure_alloc_full (tag, len, options); strcpy (res, str); return res; }
char * egg_secure_strndup_full (const char *tag, const char *str, size_t length, int options) { size_t len; char *res; const char *end; if (!str) return NULL; end = memchr (str, '\0', length); if (end != NULL) length = (end - str); len = length + 1; res = (char *)egg_secure_alloc_full (tag, len, options); memcpy (res, str, len); return res; }
void* egg_secure_alloc (size_t length) { return egg_secure_alloc_full (length, GKR_SECURE_USE_FALLBACK); }
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; }
/** * mate_keyring_memory_try_alloc: * @sz: The new desired size of the memory block. * * Allocate a block of mate-keyring non-pageable memory. * * If non-pageable memory cannot be allocated, then NULL is returned. * * Return value: The new block, or NULL if memory cannot be allocated. * The memory block should be freed with mate_keyring_memory_free() */ gpointer mate_keyring_memory_try_alloc (gulong sz) { return egg_secure_alloc_full (sz, 0); }