summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rw-r--r--doc/gcrypt.texi18
-rw-r--r--src/gcrypt.h.in4
-rw-r--r--src/global.c13
-rw-r--r--src/secmem.c29
-rw-r--r--src/secmem.h2
6 files changed, 59 insertions, 9 deletions
diff --git a/NEWS b/NEWS
index 5dea5520..ac609930 100644
--- a/NEWS
+++ b/NEWS
@@ -68,6 +68,8 @@ Noteworthy changes in version 1.6.0 (unreleased)
GCRYPT_VERSION_NUMBER NEW.
GCRY_KDF_SCRYPT NEW.
gcry_pubkey_get_sexp NEW.
+ GCRYCTL_DISABLE_LOCKED_SECMEM NEW.
+ GCRYCTL_DISABLE_PRIV_DROP NEW.
Noteworthy changes in version 1.5.0 (2011-06-29)
diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi
index d4c41940..4d244756 100644
--- a/doc/gcrypt.texi
+++ b/doc/gcrypt.texi
@@ -679,6 +679,24 @@ Many applications do not require secure memory, so they should disable
it right away. This command should be executed right after
@code{gcry_check_version}.
+@item GCRYCTL_DISABLE_LOCKED_SECMEM; Arguments: none
+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}.
+
+@item GCRYCTL_DISABLE_PRIV_DROP; Arguments: none
+This command sets a global flag to tell the secure memory subsystem
+that it shall not drop privileges after secure memory has been
+allocated. This command is commonly used right after
+@code{gcry_check_version} but may also be used right away at program
+startup. It won't have an effect after the secure memory pool has
+been initialized. WARNING: A process running setuid(root) is a severe
+security risk. Processes making use of Libgcrypt or other complex
+code should drop these extra privileges as soon as possible. If this
+command has been used the caller is responsible for dropping the
+privileges.
+
@item GCRYCTL_INIT_SECMEM; Arguments: int nbytes
This command is used to allocate a pool of secure memory and thus
enabling the use of secure memory. It also drops all extra privileges
diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in
index f472b02b..27a29ec2 100644
--- a/src/gcrypt.h.in
+++ b/src/gcrypt.h.in
@@ -302,7 +302,9 @@ enum gcry_ctl_cmds
GCRYCTL_DISABLE_HWF = 63,
GCRYCTL_SET_ENFORCED_FIPS_FLAG = 64,
GCRYCTL_SET_PREFERRED_RNG_TYPE = 65,
- GCRYCTL_GET_CURRENT_RNG_TYPE = 66
+ GCRYCTL_GET_CURRENT_RNG_TYPE = 66,
+ GCRYCTL_DISABLE_LOCKED_SECMEM = 67,
+ GCRYCTL_DISABLE_PRIV_DROP = 68
};
/* Perform various operations defined by CMD. */
diff --git a/src/global.c b/src/global.c
index f8738975..a6fe9804 100644
--- a/src/global.c
+++ b/src/global.c
@@ -2,6 +2,7 @@
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
* 2004, 2005, 2006, 2008, 2011,
* 2012 Free Software Foundation, Inc.
+ * Copyright (C) 2013 g10 Code GmbH
*
* This file is part of Libgcrypt.
*
@@ -687,6 +688,18 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
}
break;
+ case GCRYCTL_DISABLE_LOCKED_SECMEM:
+ _gcry_set_preferred_rng_type (0);
+ _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
+ | GCRY_SECMEM_FLAG_NO_MLOCK));
+ break;
+
+ case GCRYCTL_DISABLE_PRIV_DROP:
+ _gcry_set_preferred_rng_type (0);
+ _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
+ | GCRY_SECMEM_FLAG_NO_PRIV_DROP));
+ break;
+
default:
_gcry_set_preferred_rng_type (0);
err = GPG_ERR_INV_OP;
diff --git a/src/secmem.c b/src/secmem.c
index 107c6626..c350bc93 100644
--- a/src/secmem.c
+++ b/src/secmem.c
@@ -1,6 +1,7 @@
/* secmem.c - memory allocation from a secure heap
* Copyright (C) 1998, 1999, 2000, 2001, 2002,
* 2003, 2007 Free Software Foundation, Inc.
+ * Copyright (C) 2013 g10 Code GmbH
*
* This file is part of Libgcrypt.
*
@@ -78,6 +79,8 @@ static int show_warning;
static int not_locked;
static int no_warning;
static int suspend_warning;
+static int no_mlock;
+static int no_priv_drop;
/* Stats. */
static unsigned int cur_alloced, cur_blocks;
@@ -241,7 +244,7 @@ lock_pool (void *p, size_t n)
int err;
cap_set_proc (cap_from_text ("cap_ipc_lock+ep"));
- err = mlock (p, n);
+ err = no_mlock? 0 : mlock (p, n);
if (err && errno)
err = errno;
cap_set_proc (cap_from_text ("cap_ipc_lock+p"));
@@ -282,22 +285,27 @@ lock_pool (void *p, size_t n)
}
else
{
- err = mlock (p, n);
+ err = no_mlock? 0 : mlock (p, n);
if (err && errno)
err = errno;
}
#else /* !HAVE_BROKEN_MLOCK */
- err = mlock (p, n);
+ err = no_mlock? 0 : mlock (p, n);
if (err && errno)
err = errno;
#endif /* !HAVE_BROKEN_MLOCK */
+ /* Test whether we are running setuid(0). */
if (uid && ! geteuid ())
{
- /* check that we really dropped the privs.
- * Note: setuid(0) should always fail */
- if (setuid (uid) || getuid () != geteuid () || !setuid (0))
- log_fatal ("failed to reset uid: %s\n", strerror (errno));
+ /* Yes, we are. */
+ if (!no_priv_drop)
+ {
+ /* Check that we really dropped the privs.
+ * Note: setuid(0) should always fail */
+ if (setuid (uid) || getuid () != geteuid () || !setuid (0))
+ log_fatal ("failed to reset uid: %s\n", strerror (errno));
+ }
}
if (err)
@@ -339,7 +347,8 @@ lock_pool (void *p, size_t n)
#else
(void)p;
(void)n;
- log_info ("Please note that you don't have secure memory on this system\n");
+ if (!no_mlock)
+ log_info ("Please note that you don't have secure memory on this system\n");
#endif
}
@@ -424,6 +433,8 @@ _gcry_secmem_set_flags (unsigned flags)
was_susp = suspend_warning;
no_warning = flags & GCRY_SECMEM_FLAG_NO_WARNING;
suspend_warning = flags & GCRY_SECMEM_FLAG_SUSPEND_WARNING;
+ no_mlock = flags & GCRY_SECMEM_FLAG_NO_MLOCK;
+ no_priv_drop = flags & GCRY_SECMEM_FLAG_NO_PRIV_DROP;
/* and now issue the warning if it is not longer suspended */
if (was_susp && !suspend_warning && show_warning)
@@ -445,6 +456,8 @@ _gcry_secmem_get_flags (void)
flags = no_warning ? GCRY_SECMEM_FLAG_NO_WARNING : 0;
flags |= suspend_warning ? GCRY_SECMEM_FLAG_SUSPEND_WARNING : 0;
flags |= not_locked ? GCRY_SECMEM_FLAG_NOT_LOCKED : 0;
+ flags |= no_mlock ? GCRY_SECMEM_FLAG_NO_MLOCK : 0;
+ flags |= no_priv_drop ? GCRY_SECMEM_FLAG_NO_PRIV_DROP : 0;
SECMEM_UNLOCK;
diff --git a/src/secmem.h b/src/secmem.h
index 29e151af..3577381c 100644
--- a/src/secmem.h
+++ b/src/secmem.h
@@ -35,5 +35,7 @@ int _gcry_private_is_secure (const void *p);
#define GCRY_SECMEM_FLAG_NO_WARNING (1 << 0)
#define GCRY_SECMEM_FLAG_SUSPEND_WARNING (1 << 1)
#define GCRY_SECMEM_FLAG_NOT_LOCKED (1 << 2)
+#define GCRY_SECMEM_FLAG_NO_MLOCK (1 << 3)
+#define GCRY_SECMEM_FLAG_NO_PRIV_DROP (1 << 4)
#endif /* G10_SECMEM_H */