Page MenuHome GnuPG

clear text visible in a core dump even though gpgme_data_release was called to clear data
Closed, ResolvedPublic

Description

Our test program uses libgpgme to decrypt a file. We force it to core dump
after calling gpgme_data_release (which should delete the clear text password).
Upon inspection of the core we are able to recover the password which we
thought gpgme_data_release would prevent.

  1. Here is the encrypted file:

$ cat mumps.x
-----BEGIN PGP MESSAGE-----
Version: GnuPG v1.4.5 (GNU/Linux)

hQEMA0aWTbujSLQjAQf/Tihsg2LlCszvWWGWOWFdcWP3s78ExjpFGDhHYQNJ0wEq
04JTKUuXDRlbp45SWzHiG9iRZoFMh0lJvYSU6ILUgfOWb+J/DYhW+COmOxDF+LeG
VZeJDyRQr6esI3pYupuPvXPHxDf9gtQEbfPzsZrIgsPmGUXrkc+jnD4zzzAv9BId
OtMJeTDV8wwbClOL/OPyN8+LswzAFgU74oqXQhfocFS6Ipco+LXOmtCr7c7NmagJ
c3++qQKU7iExJAyO1/kIlS9YsWPDH4nf/5K26u3d2yKnGjzAFHPqEsXyj9dkySVW
8alQy+MzUkiW/ojpie7cgUxbSV2Q5d9pe8TveS9p+tJcAWHRdWU0pBW3P8tR86FS
xKPDvQT9M9VOZethMz/l0KtBq4jG+uR5Ej9ZUy/FV8ow2ELHfhMgv37o8VVk4/hm
CzJD4vHCU0b9d69MEXxhETt7LyXAntL9iAkHly0=

SlCZ

-----END PGP MESSAGE-----

  1. Here is the plain text

$ gpg -d mumps.x

You need a passphrase to unlock the secret key for
user: "Alice (Comment) <alice@bob.com>"
2048-bit RSA key, ID A348B423, created 2009-04-30 (main key ID 6414F131)

gpg: encrypted with 2048-bit RSA key, ID A348B423, created 2009-04-30

"Alice (Comment) <alice@bob.com>"

bacdefghijklmnopqrstuvwxyz123456

  1. Run a program that decrypts the file via libgpgme and properly calls

gpgme_data_release() (and crashes):

$ ./test_gpgme ß The password on the command line has been suppressed.
Quit (core dumped)
$ strings core.6178| grep bacdefghi
bacdefghijklmnopqrstuvwxyz123456 ß The clear text shows up in the core.
bacdefghijklmnopqrstuvwxyz123456

The affected platforms are:
OS (HW) -- libgpgme
Ubuntu 8.04 LTS (x86_64) -- 1.1.5-2
RHEL 5.2 (x86_64) -- 1.1.4
RHEL 4 .7 (x86) -- 1.0.3
RHEL 5 .3(IA64) -- 1.1.4
z/OS (zSeries) -- 1.1.8
AIX 5.3 (pSeries) -- 1.1.8 + fix
Solaris 9 and 10 (SPARC) -- 1.1.4
HP-UX 11.31 (IA64) -- 1.1.8 + fix

Details

Version
1.1.8

Event Timeline

werner claimed this task.
werner added a project: Not A Bug.

So you are using the passpharse callback of gpgme and don't make use
ofgpg-agent. In that case you need to take care of zeroing the passphrase.
gpgme has no provisionhs for this because the passphrase callback is a feature
obnly useful in certain environments. gpgme_data_t has nothing to do with
passpphrases.

Use gpg-agent.

BTW:

static int scrub_stack()
{
char arr[8192];

memset(arr, 0, 8192);
return 0;
}

This does not work. Even if that fucntion is used the compiler removes the
memset. The same thing happens for the memset at the end of main. You need to
use code like:

/* To avoid that a compiler optimizes certain memset calls away, these

macros may be used instead. */

#define wipememory2(_ptr,_set,_len) do { \

volatile char *_vptr=(volatile char *)(_ptr); \
size_t _vlen=(_len); \
while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \
    } while(0)

#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len)

Wrong title. It is not that the password is visible but that the clear text
from the gpgme_opt_decrypt function is visible. Another developer with more
knowledge of the scenario in this issue will respond shortly.

amul renamed this task from password visible in a core dump even though gpgme_data_release was called to clear data to clear text visible in a core dump even though gpgme_data_release was called to clear data.Jul 29 2009, 7:32 PM
amul removed gtmbill as the assignee of this task.Jul 30 2009, 3:15 PM

Forwarding for Bill.

Werner:

So for the confusion. The issue we had was that (based upon the file that Amul
uploaded):

80 err = gpgme_data_new_from_file(&cipher_data, cipher_file, 1); <-- get
data from encrypted file

89 err = gpgme_op_decrypt(context, cipher_data,
plain_data); <--decrypt the data
...
95 *plain_text_length =
retrieve_plain_text(plain_data, plain_text); <--get the plain text
...
100 gpgme_data_release(plain_data); <--destroy the data
...
102 gpgme_data_release(cipher_data); <--destroy the data

And the clear text from the decrypted file shows up in the core file even though
gpgme_data_release was called to destroy the data objects.

Thanks
Bill

I see. Your plaintext needs to be zeroized after decryption and processing by
you. gpgme does not directly support this. What you can do for data objects
hold in memory is:

char *p = gpgme_data_release_and_get_mem (plain_data, &plain_datalen);
if (p)
   {
      wipememory (p, plain_datalen);
      gpgme_free (p);
   }

If that is not sufficient you may use your own callbacks for the data handlers.
Note that some internal buffers may still hold parts ofthe plaintext. If you
need a better assurance please contact my company.

werner claimed this task.