diff options
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | doc/gcrypt.texi | 18 | ||||
-rw-r--r-- | src/gcrypt.h.in | 4 | ||||
-rw-r--r-- | src/global.c | 13 | ||||
-rw-r--r-- | src/secmem.c | 29 | ||||
-rw-r--r-- | src/secmem.h | 2 |
6 files changed, 59 insertions, 9 deletions
@@ -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 */ |