tests: New test t-secmem.
authorWerner Koch <wk@gnupg.org>
Wed, 7 Dec 2016 09:01:39 +0000 (10:01 +0100)
committerWerner Koch <wk@gnupg.org>
Wed, 7 Dec 2016 09:01:39 +0000 (10:01 +0100)
* src/secmem.c (_gcry_secmem_dump_stats): Add arg EXTENDED and adjust
caller.
* src/gcrypt-testapi.h (PRIV_CTL_DUMP_SECMEM_STATS): New.
* src/global.c (_gcry_vcontrol): Implement that.
* tests/t-secmem.c: New.
* tests/Makefile.am (tests_bin): Add that test.
--

This test does not much right now.

Signed-off-by: Werner Koch <wk@gnupg.org>
src/gcrypt-testapi.h
src/global.c
src/secmem.c
src/secmem.h
tests/Makefile.am
tests/t-secmem.c [new file with mode: 0644]

index 23d3800..0417754 100644 (file)
@@ -31,6 +31,7 @@
 #define PRIV_CTL_RUN_EXTRNG_TEST    59
 #define PRIV_CTL_DEINIT_EXTRNG_TEST 60
 #define PRIV_CTL_EXTERNAL_LOCK_TEST 61
+#define PRIV_CTL_DUMP_SECMEM_STATS  62
 
 #define EXTERNAL_LOCK_TEST_INIT       30111
 #define EXTERNAL_LOCK_TEST_LOCK       30112
index 8e54efe..be112b7 100644 (file)
@@ -380,7 +380,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
       break;
 
     case GCRYCTL_DUMP_SECMEM_STATS:
-      _gcry_secmem_dump_stats ();
+      _gcry_secmem_dump_stats (0);
       break;
 
     case GCRYCTL_DROP_PRIVS:
@@ -613,7 +613,8 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
     case PRIV_CTL_EXTERNAL_LOCK_TEST:  /* Run external lock test */
       rc = external_lock_test (va_arg (arg_ptr, int));
       break;
-    case 62:  /* RFU */
+    case PRIV_CTL_DUMP_SECMEM_STATS:
+      _gcry_secmem_dump_stats (1);
       break;
 #if _GCRY_GCC_VERSION >= 40600
 # pragma GCC diagnostic pop
index 1f92f17..54bbda1 100644 (file)
@@ -751,33 +751,35 @@ _gcry_secmem_term ()
 }
 
 
+/* Print stats of the secmem allocator.  With EXTENDED passwed as true
+ * a detiled listing is returned (used for testing).  */
 void
-_gcry_secmem_dump_stats ()
+_gcry_secmem_dump_stats (int extended)
 {
   pooldesc_t *pool;
-
-#if 1
-  SECMEM_LOCK;
-
-  pool = &mainpool;
-  if (pool->okay)
-    log_info ("secmem usage: %u/%lu bytes in %u blocks\n",
-             cur_alloced, (unsigned long)pool->size, cur_blocks);
-  SECMEM_UNLOCK;
-#else
   memblock_t *mb;
   int i;
 
   SECMEM_LOCK;
 
   pool = &mainpool;
-  for (i = 0, mb = (memblock_t *) pool->mem;
-       ptr_into_pool_p (pool, mb);
-       mb = mb_get_next (pool, mb), i++)
-    log_info ("SECMEM: [%s] block: %i; size: %i\n",
-             (mb->flags & MB_FLAG_ACTIVE) ? "used" : "free",
-             i,
-             mb->size);
+  if (!extended)
+    {
+      if (pool->okay)
+        log_info ("secmem usage: %u/%lu bytes in %u blocks\n",
+                  cur_alloced, (unsigned long)pool->size, cur_blocks);
+    }
+  else
+    {
+      for (i = 0, mb = (memblock_t *) pool->mem;
+           ptr_into_pool_p (pool, mb);
+           mb = mb_get_next (pool, mb), i++)
+        log_info ("SECMEM: pool %p %s block %i size %i\n",
+                  pool,
+                  (mb->flags & MB_FLAG_ACTIVE) ? "used" : "free",
+                  i,
+                  mb->size);
+      }
+
   SECMEM_UNLOCK;
-#endif
 }
index 3577381..764bfeb 100644 (file)
@@ -26,7 +26,7 @@ void _gcry_secmem_term (void);
 void *_gcry_secmem_malloc (size_t size) _GCRY_GCC_ATTR_MALLOC;
 void *_gcry_secmem_realloc (void *a, size_t newsize);
 void _gcry_secmem_free (void *a);
-void _gcry_secmem_dump_stats (void);
+void _gcry_secmem_dump_stats (int extended);
 void _gcry_secmem_set_flags (unsigned flags);
 unsigned _gcry_secmem_get_flags(void);
 int _gcry_private_is_secure (const void *p);
index d462f30..374e72e 100644 (file)
@@ -19,7 +19,7 @@
 ## Process this file with automake to produce Makefile.in
 
 tests_bin = \
-        version mpitests t-sexp t-convert \
+        version t-secmem mpitests t-sexp t-convert \
        t-mpi-bit t-mpi-point curves t-lock \
        prime basic keygen pubkey hmac hashtest t-kdf keygrip \
        fips186-dsa aeswrap pkcs1v2 random dsa-rfc6979 t-ed25519 t-cv25519
diff --git a/tests/t-secmem.c b/tests/t-secmem.c
new file mode 100644 (file)
index 0000000..b464d02
--- /dev/null
@@ -0,0 +1,141 @@
+/* t-secmem.c - Test the secmem memory allocator
+ * Copyright (C) 2016 g10 Code GmbH
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#define PGMNAME "t-secmem"
+
+#include "t-common.h"
+#include "../src/gcrypt-testapi.h"
+
+
+static void
+test_secmem (void)
+{
+  void *a[28];
+  void *b;
+  int i;
+
+  memset (a, 0, sizeof a);
+
+  /* Allocating 28*512=14k should work in the default 16k pool even
+   * with extrem alignment requirements.  */
+  for (i=0; i < DIM(a); i++)
+    a[i] = gcry_xmalloc_secure (512);
+
+  /* Allocating another 2k should fail for the default 16k pool.  */
+  b = gcry_malloc_secure (2048);
+  if (b)
+    fail ("allocation did not fail as expected\n");
+
+  for (i=0; i < DIM(a); i++)
+    xfree (a[i]);
+  xfree (b);
+}
+
+
+/* This function is called when we ran out of core and there is no way
+ * to return that error to the caller (xmalloc or mpi allocation).  */
+static int
+outofcore_handler (void *opaque, size_t req_n, unsigned int flags)
+{
+  static int been_here;  /* Used to protect against recursive calls. */
+
+  (void)opaque;
+
+  /* Protect against a second call.  */
+  if (been_here)
+    return 0; /* Let libgcrypt call its own fatal error handler.  */
+  been_here = 1;
+
+  info ("outofcore handler invoked");
+  gcry_control (PRIV_CTL_DUMP_SECMEM_STATS, 0 , 0);
+  fail ("out of core%s while allocating %lu bytes",
+       (flags & 1)?" in secure memory":"", (unsigned long)req_n);
+
+  die ("stopped");
+  /*NOTREACHED*/
+  return 0;
+}
+
+
+int
+main (int argc, char **argv)
+{
+  int last_argc = -1;
+
+  if (argc)
+    { argc--; argv++; }
+
+  while (argc && last_argc != argc )
+    {
+      last_argc = argc;
+      if (!strcmp (*argv, "--"))
+        {
+          argc--; argv++;
+          break;
+        }
+      else if (!strcmp (*argv, "--help"))
+        {
+          fputs ("usage: " PGMNAME " [options]\n"
+                 "Options:\n"
+                 "  --verbose       print timings etc.\n"
+                 "  --debug         flyswatter\n"
+                 , stdout);
+          exit (0);
+        }
+      else if (!strcmp (*argv, "--verbose"))
+        {
+          verbose++;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--debug"))
+        {
+          verbose += 2;
+          debug++;
+          argc--; argv++;
+        }
+      else if (!strncmp (*argv, "--", 2))
+        die ("unknown option '%s'", *argv);
+    }
+
+  if (!gcry_check_version (GCRYPT_VERSION))
+    die ("version mismatch; pgm=%s, library=%s\n",
+         GCRYPT_VERSION, gcry_check_version (NULL));
+  if (debug)
+    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
+  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+  gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
+  gcry_set_outofcore_handler (outofcore_handler, NULL);
+  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+
+  test_secmem ();
+
+  if (verbose)
+    gcry_control (PRIV_CTL_DUMP_SECMEM_STATS, 0 , 0);
+  info ("All tests completed.  Errors: %d\n", errorcount);
+  return !!errorcount;
+}