summaryrefslogtreecommitdiffstats
path: root/util/memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/memory.c')
-rw-r--r--util/memory.c137
1 files changed, 90 insertions, 47 deletions
diff --git a/util/memory.c b/util/memory.c
index 1ef1da64d..6ed35966f 100644
--- a/util/memory.c
+++ b/util/memory.c
@@ -4,13 +4,11 @@
* We use our own memory allocation functions instead of plain malloc(),
* so that we can provide some special enhancements:
* a) functions to provide memory from a secure memory.
- * Don't know how to handle it yet, but it may be possible to
- * use memory which can't be swapped out.
* b) By looking at the requested allocation size we
* can reuse memory very quickly (e.g. MPI storage)
- * c) A controlbyte gives us the opportunity to use only one
- * free() function and do some overflow checking.
- * d) memory checking and reporting if compiled with M_DEBUG
+ * (really needed?)
+ * c) memory usage reporting if compiled with M_DEBUG
+ * d) memory checking if compiled with M_GUARD
*
* This file is part of GNUPG.
*
@@ -44,9 +42,18 @@
#define MAGIC_SEC_BYTE 0xcc
#define MAGIC_END_BYTE 0xaa
+#if SIZEOF_UNSIGNED_LONG == 8
+ #define EXTRA_ALIGN 4
+#else
+ #define EXTRA_ALIGN 0
+#endif
+
const void membug( const char *fmt, ... );
#ifdef M_DEBUG
+ #ifndef M_GUARD
+ #define M_GUARD 1
+ #endif
#undef m_alloc
#undef m_alloc_clear
#undef m_alloc_secure
@@ -64,10 +71,10 @@ const void membug( const char *fmt, ... );
#define FNAME(a) m_ ##a
#define FNAMEPRT
#define FNAMEARG
- #define store_len(p,n,m) do { ((byte*)p)[0] = n; \
- ((byte*)p)[1] = n >> 8 ; \
- ((byte*)p)[2] = n >> 16 ; \
- ((byte*)p)[3] = m? MAGIC_SEC_BYTE \
+ #define store_len(p,n,m) do { ((byte*)p)[EXTRA_ALIGN+0] = n; \
+ ((byte*)p)[EXTRA_ALIGN+1] = n >> 8 ; \
+ ((byte*)p)[EXTRA_ALIGN+2] = n >> 16 ; \
+ ((byte*)p)[EXTRA_ALIGN+3] = m? MAGIC_SEC_BYTE \
: MAGIC_NOR_BYTE; \
} while(0)
#endif
@@ -196,24 +203,29 @@ check_mem( const byte *p, const char *info )
unsigned n;
struct memtbl_entry *e;
- n = p[0];
- n |= p[1] << 8;
- n |= p[2] << 16;
+ n = p[EXTRA_ALIGN+0];
+ n |= p[EXTRA_ALIGN+1] << 8;
+ n |= p[EXTRA_ALIGN+2] << 16;
if( n >= memtbl_len )
membug("memory at %p corrupted: index=%u table_len=%u (%s)\n",
- p+4, n, memtbl_len, info );
+ p+EXTRA_ALIGN+4, n, memtbl_len, info );
e = memtbl+n;
- if( e->user_p != p+4 )
- membug("memory at %p corrupted: reference mismatch (%s)\n", p+4, info );
+ if( e->user_p != p+EXTRA_ALIGN+4 )
+ membug("memory at %p corrupted: reference mismatch (%s)\n",
+ p+EXTRA_ALIGN+4, info );
if( !e->inuse )
- membug("memory at %p corrupted: marked as free (%s)\n", p+4, info );
-
- if( !(p[3] == MAGIC_NOR_BYTE || p[3] == MAGIC_SEC_BYTE) )
- membug("memory at %p corrupted: underflow=%02x (%s)\n", p+4, p[3], info );
- if( p[4+e->user_n] != MAGIC_END_BYTE )
- membug("memory at %p corrupted: overflow=%02x (%s)\n", p+4, p[4+e->user_n], info );
+ membug("memory at %p corrupted: marked as free (%s)\n",
+ p+EXTRA_ALIGN+4, info );
+
+ if( !(p[EXTRA_ALIGN+3] == MAGIC_NOR_BYTE
+ || p[EXTRA_ALIGN+3] == MAGIC_SEC_BYTE) )
+ membug("memory at %p corrupted: underflow=%02x (%s)\n",
+ p+EXTRA_ALIGN+4, p[EXTRA_ALIGN+3], info );
+ if( p[EXTRA_ALIGN+4+e->user_n] != MAGIC_END_BYTE )
+ membug("memory at %p corrupted: overflow=%02x (%s)\n",
+ p+EXTRA_ALIGN+4, p[EXTRA_ALIGN+4+e->user_n], info );
return e;
}
@@ -233,10 +245,10 @@ free_entry( byte *p, const char *info )
log_debug( "%s frees %u bytes alloced by %s\n",
info, e->user_n, e->info->info );
if( !e->inuse ) {
- if( e->user_p == p + 4 )
- membug("freeing an already freed pointer at %p\n", p+4 );
+ if( e->user_p == p + EXTRA_ALIGN+ 4 )
+ membug("freeing an already freed pointer at %p\n", p+EXTRA_ALIGN+4 );
else
- membug("freeing pointer %p which is flagged as freed\n", p+4 );
+ membug("freeing pointer %p which is flagged as freed\n", p+EXTRA_ALIGN+4 );
}
e->inuse = 0;
@@ -298,7 +310,7 @@ check_allmem( const char *info )
for( e = memtbl, n = 0; n < memtbl_len; n++, e++ )
if( e->inuse )
- check_mem(e->user_p-4, info);
+ check_mem(e->user_p-4-EXTRA_ALIGN, info);
}
#endif /* M_DEBUG */
@@ -337,11 +349,17 @@ FNAME(alloc)( size_t n FNAMEPRT )
{
char *p;
- if( !(p = malloc( n + 5 )) )
+ #ifdef M_GUARD
+ if( !(p = malloc( n + EXTRA_ALIGN+5 )) )
out_of_core(n,0);
store_len(p,n,0);
- p[4+n] = MAGIC_END_BYTE; /* need to add the length somewhere */
- return p+4;
+ p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE;
+ return p+EXTRA_ALIGN+4;
+ #else
+ if( !(p = malloc( n )) )
+ out_of_core(n,0);
+ return p;
+ #endif
}
/****************
@@ -353,11 +371,17 @@ FNAME(alloc_secure)( size_t n FNAMEPRT )
{
char *p;
- if( !(p = secmem_malloc( n + 5 )) )
+ #ifdef M_GUARD
+ if( !(p = secmem_malloc( n +EXTRA_ALIGN+ 5 )) )
out_of_core(n,1);
store_len(p,n,1);
- p[4+n] = MAGIC_END_BYTE;
- return p+4;
+ p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE;
+ return p+EXTRA_ALIGN+4;
+ #else
+ if( !(p = secmem_malloc( n )) )
+ out_of_core(n,1);
+ return p;
+ #endif
}
void *
@@ -384,7 +408,8 @@ FNAME(alloc_secure_clear)( size_t n FNAMEPRT)
*/
void *
FNAME(realloc)( void *a, size_t n FNAMEPRT )
-{ /* FIXME: should be optimized :-) */
+{
+ #ifdef M_GUARD
unsigned char *p = a;
void *b;
size_t len = m_size(a);
@@ -398,6 +423,18 @@ FNAME(realloc)( void *a, size_t n FNAMEPRT )
FNAME(check)(NULL FNAMEARG);
memcpy(b, a, len );
FNAME(free)(p FNAMEARG);
+ #else
+ void *b;
+
+ if( m_is_secure(a) ) {
+ if( !(b = secmem_realloc( a, n )) )
+ out_of_core(n,1);
+ }
+ else {
+ if( !(b = realloc( a, n )) )
+ out_of_core(n,0);
+ }
+ #endif
return b;
}
@@ -414,13 +451,18 @@ FNAME(free)( void *a FNAMEPRT )
if( !p )
return;
#ifdef M_DEBUG
- free_entry(p-4, info);
- #else
+ free_entry(p-EXTRA_ALIGN-4, info);
+ #elif M_GUARD
m_check(p);
if( m_is_secure(a) )
- secmem_free(p-4);
+ secmem_free(p-EXTRA_ALIGN-4);
else
- free(p-4);
+ free(p-EXTRA_ALIGN-4);
+ #else
+ if( m_is_secure(a) )
+ secmem_free(p);
+ else
+ free(p);
#endif
}
@@ -428,11 +470,12 @@ FNAME(free)( void *a FNAMEPRT )
void
FNAME(check)( const void *a FNAMEPRT )
{
+ #ifdef M_GUARD
const byte *p = a;
#ifdef M_DEBUG
if( p )
- check_mem(p-4, info);
+ check_mem(p-EXTRA_ALIGN-4, info);
else
check_allmem(info);
#else
@@ -443,33 +486,33 @@ FNAME(check)( const void *a FNAMEPRT )
else if( p[m_size(p)] != MAGIC_END_BYTE )
membug("memory at %p corrupted (overflow=%02x)\n", p, p[-1] );
#endif
+ #endif
}
size_t
m_size( const void *a )
{
+ #ifndef M_GUARD
+ log_debug("Ooops, m_size called\n");
+ return 0;
+ #else
const byte *p = a;
size_t n;
#ifdef M_DEBUG
- n = check_mem(p-4, "m_size")->user_n;
+ n = check_mem(p-EXTRA_ALIGN-4, "m_size")->user_n;
#else
n = ((byte*)p)[-4];
n |= ((byte*)p)[-3] << 8;
n |= ((byte*)p)[-2] << 16;
#endif
return n;
+ #endif
}
-int
-m_is_secure( const void *p )
-{
- return p && ((byte*)p)[-1] == MAGIC_SEC_BYTE;
-}
-
-
+#if 0 /* not used */
/****************
* Make a copy of the memory block at a
*/
@@ -482,7 +525,7 @@ FNAME(copy)( const void *a FNAMEPRT )
if( !a )
return NULL;
- n = m_size(a);
+ n = m_size(a); Aiiiih woher nehmen
if( m_is_secure(a) )
b = FNAME(alloc_secure)(n FNAMEARG);
else
@@ -490,7 +533,7 @@ FNAME(copy)( const void *a FNAMEPRT )
memcpy(b, a, n );
return b;
}
-
+#endif
char *
FNAME(strdup)( const char *a FNAMEPRT )