summaryrefslogtreecommitdiff
path: root/src/secmem.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2013-04-18 14:40:43 +0200
committerWerner Koch <wk@gnupg.org>2013-05-22 17:59:29 +0200
commit2b8014af202c9e0f7619f7a4377f5eb752235220 (patch)
tree16f4498cfa6823f13d00467444fc856c2896e799 /src/secmem.c
parent05b3e2dda61d3d532a7f1ffd2487a85ed1c4f3ab (diff)
downloadlibgcrypt-2b8014af202c9e0f7619f7a4377f5eb752235220.tar.gz
Add control commands to disable mlock and setuid dropping.
* src/gcrypt.h.in (GCRYCTL_DISABLE_LOCKED_SECMEM): New. (GCRYCTL_DISABLE_PRIV_DROP): New. * src/global.c (_gcry_vcontrol): Implement them. * src/secmem.h (GCRY_SECMEM_FLAG_NO_MLOCK): New. (GCRY_SECMEM_FLAG_NO_PRIV_DROP): New. * src/secmem.c (no_mlock, no_priv_drop): New. (_gcry_secmem_set_flags, _gcry_secmem_get_flags): Set and get them. (lock_pool): Handle no_mlock and no_priv_drop. Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'src/secmem.c')
-rw-r--r--src/secmem.c29
1 files changed, 21 insertions, 8 deletions
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;