/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ /* gcr-secure-memory.c - library for allocating memory that is non-pageable Copyright (C) 2007 Stefan Walter Copyright (C) 2012 Red Hat Inc. The Gnome Keyring Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The Gnome Keyring Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the Gnome Library; see the file COPYING.LIB. If not, see . Author: Stef Walter */ #include "config.h" #include "gcr-secure-memory.h" #include "egg/egg-secure-memory.h" #include #include /** * gcr_secure_memory_new: (skip) * @type: C type of the objects to allocate * @n_objects: number of objects to allocate * * Allocate objects in non-pageable memory. * * Returns: (transfer full): the new block of memory **/ /** * gcr_secure_memory_alloc: (skip) * @size: The new desired size of the memory block. * * Allocate a block of non-pageable memory. * * If non-pageable memory cannot be allocated then normal memory will be * returned. * * Return value: (transfer full): new memory block which should be freed * with gcr_secure_memory_free() **/ gpointer gcr_secure_memory_alloc (gsize size) { gpointer memory; /* Try to allocate secure memory */ memory = egg_secure_alloc_full ("gcr-secure-memory", size, EGG_SECURE_USE_FALLBACK); /* Our fallback will always allocate */ g_assert (memory != NULL); return memory; } /** * gcr_secure_memory_try_alloc: (skip) * @size: new desired size of the memory block * * Allocate a block of non-pageable memory. * * If non-pageable memory cannot be allocated, then %NULL is returned. * * Return value: (transfer full): new block, or %NULL if memory cannot be * allocated; memory block should be freed with gcr_secure_memory_free() */ gpointer gcr_secure_memory_try_alloc (gsize size) { return egg_secure_alloc_full ("gcr-secure-memory", size, 0); } /** * gcr_secure_memory_realloc: (skip) * @memory: (nullable): pointer to reallocate or %NULL to allocate a new block * @size: new desired size of the memory block, or 0 to free the memory * * Reallocate a block of non-pageable memory. * * Glib memory is also reallocated correctly. If called with a null pointer, * then a new block of memory is allocated. If called with a zero size, * then the block of memory is freed. * * If non-pageable memory cannot be allocated then normal memory will be * returned. * * Return value: (transfer full): new block, or %NULL if the block was * freed; memory block should be freed with gcr_secure_memory_free() */ gpointer gcr_secure_memory_realloc (gpointer memory, gsize size) { gpointer new_memory; if (!memory) { return gcr_secure_memory_alloc (size); } else if (!size) { gcr_secure_memory_free (memory); return NULL; } else if (!egg_secure_check (memory)) { return g_realloc (memory, size); } /* First try and ask secure memory to reallocate */ new_memory = egg_secure_realloc_full ("gcr-secure-memory", memory, size, EGG_SECURE_USE_FALLBACK); g_assert (new_memory != NULL); return new_memory; } /** * gcr_secure_memory_try_realloc: (skip) * @memory: (nullable): pointer to reallocate or %NULL to allocate a new block * @size: new desired size of the memory block * * Reallocate a block of non-pageable memory. * * Glib memory is also reallocated correctly when passed to this function. * If called with a null pointer, then a new block of memory is allocated. * If called with a zero size, then the block of memory is freed. * * If memory cannot be allocated, %NULL is returned and the original block * of memory remains intact. * * Return value: (transfer full): the new block, or %NULL if memory cannot be * allocated; the memory block should be freed with gcr_secure_memory_free() */ gpointer gcr_secure_memory_try_realloc (gpointer memory, gsize size) { gpointer new_memory; if (!memory) { return gcr_secure_memory_try_alloc (size); } else if (!size) { gcr_secure_memory_free (memory); return NULL; } else if (!egg_secure_check (memory)) { return g_try_realloc (memory, size); } /* First try and ask secure memory to reallocate */ new_memory = egg_secure_realloc_full ("gcr-secure-memory", memory, size, 0); /* Might be NULL if reallocation failed. */ return new_memory; } /** * gcr_secure_memory_free: (skip) * @memory: (nullable): pointer to the beginning of the block of memory to free * * Free a block of non-pageable memory. * * Glib memory is also freed correctly when passed to this function. If called * with a %NULL pointer then no action is taken. */ void gcr_secure_memory_free (gpointer memory) { if (!memory) return; egg_secure_free_full (memory, EGG_SECURE_USE_FALLBACK); } /** * gcr_secure_memory_is_secure: (skip) * @memory: pointer to check * * Check if a pointer is in non-pageable memory allocated by. * * Returns: whether the memory is secure non-pageable memory allocated by the * Gcr library or not */ gboolean gcr_secure_memory_is_secure (gpointer memory) { return egg_secure_check (memory) ? TRUE : FALSE; } /** * gcr_secure_memory_strdup: (skip) * @string: (nullable): null terminated string to copy * * Copy a string into non-pageable memory. If the input string is %NULL, then * %NULL will be returned. * * Returns: copied string, should be freed with gcr_secure_memory_free() */ gchar * gcr_secure_memory_strdup (const gchar* string) { return egg_secure_strdup_full ("gcr-secure-memory", string, EGG_SECURE_USE_FALLBACK); } /** * gcr_secure_memory_strfree: (skip) * @string: (nullable): null terminated string to fere * * Free a string, whether securely allocated using these functions or not. * This will also clear out the contents of the string so they do not * remain in memory. */ void gcr_secure_memory_strfree (gchar *string) { egg_secure_strfree (string); }