Document the overflow pools and add a stupid test case.
authorWerner Koch <wk@gnupg.org>
Wed, 7 Dec 2016 16:01:19 +0000 (17:01 +0100)
committerWerner Koch <wk@gnupg.org>
Wed, 7 Dec 2016 16:01:19 +0000 (17:01 +0100)
* tests/t-secmem.c (test_secmem_overflow): New func.
(main): Disable warning and call new function.

Signed-off-by: Werner Koch <wk@gnupg.org>
doc/gcrypt.texi
tests/t-secmem.c

index 933d22d..cb539da 100644 (file)
@@ -422,8 +422,11 @@ and freed memory, you need to initialize Libgcrypt this way:
      process might still be running with increased privileges and that
      the secure memory has not been initialized.  */
 
-  /* Allocate a pool of 16k secure memory.  This make the secure memory
-     available and also drops privileges where needed.  */
+  /* Allocate a pool of 16k secure memory.  This makes the secure memory
+     available and also drops privileges where needed.  Note that by
+     using functions like gcry_xmalloc_secure and gcry_mpi_snew Libgcrypt
+     may extend the secure memory pool with memory which lacks the
+     property of not being swapped out to disk.   */
   gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
 
 @anchor{sample-use-resume-secmem}
@@ -667,7 +670,10 @@ it right away.  This command should be executed right after
 This command disables the use of the mlock call for secure memory.
 Disabling the use of mlock may for example be done if an encrypted
 swap space is in use.  This command should be executed right after
-@code{gcry_check_version}.
+@code{gcry_check_version}.  Note that by using functions like
+gcry_xmalloc_secure and gcry_mpi_snew Libgcrypt may extend the secure
+memory pool with memory which lacks the property of not being swapped
+out to disk (but will still be zeroed out on free).
 
 @item GCRYCTL_DISABLE_PRIV_DROP; Arguments: none
 This command sets a global flag to tell the secure memory subsystem
index b464d02..cb2313e 100644 (file)
@@ -57,6 +57,31 @@ test_secmem (void)
 }
 
 
+static void
+test_secmem_overflow (void)
+{
+  void *a[150];
+  int i;
+
+  memset (a, 0, sizeof a);
+
+  /* Allocating 150*512=75k should require more than one overflow buffer.  */
+  for (i=0; i < DIM(a); i++)
+    {
+      a[i] = gcry_xmalloc_secure (512);
+      if (verbose && !(i %40))
+        gcry_control (GCRYCTL_DUMP_SECMEM_STATS, 0 , 0);
+    }
+
+  if (debug)
+    gcry_control (PRIV_CTL_DUMP_SECMEM_STATS, 0 , 0);
+  if (verbose)
+    gcry_control (GCRYCTL_DUMP_SECMEM_STATS, 0 , 0);
+  for (i=0; i < DIM(a); i++)
+    xfree (a[i]);
+}
+
+
 /* 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
@@ -132,10 +157,24 @@ main (int argc, char **argv)
   gcry_set_outofcore_handler (outofcore_handler, NULL);
   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
 
+  /* Libgcrypt prints a warning when the first overflow is allocated;
+   * we do not want to see that.  */
+  if (!verbose)
+    gcry_control (GCRYCTL_DISABLE_SECMEM_WARN, 0);
+
+
   test_secmem ();
+  test_secmem_overflow ();
+  /* FIXME: We need to improve the tests, for example by registering
+   * our own log handler and comparing the output of
+   * PRIV_CTL_DUMP_SECMEM_STATS to expected pattern.  */
 
   if (verbose)
-    gcry_control (PRIV_CTL_DUMP_SECMEM_STATS, 0 , 0);
+    {
+      gcry_control (PRIV_CTL_DUMP_SECMEM_STATS, 0 , 0);
+      gcry_control (GCRYCTL_DUMP_SECMEM_STATS, 0 , 0);
+    }
   info ("All tests completed.  Errors: %d\n", errorcount);
+  gcry_control (GCRYCTL_TERM_SECMEM, 0 , 0);
   return !!errorcount;
 }