OpenSSH 3.2.2p1 sshd: fatal: xfree: NULL pointer given as argument

Phil Howard phil-openssh-unix-dev at ipal.net
Tue May 21 04:27:01 EST 2002


On Sat, May 18, 2002 at 03:56:44PM -0700, Kevin Steves wrote:

| On Sat, May 18, 2002 at 07:53:50AM -0500, Phil Howard wrote:
| > debug1: dh_gen_key: priv key bits set: 194/384
| > debug1: bits set: 1047/2049
| > debug1: expecting SSH2_MSG_KEX_DH_GEX_INIT
| > debug1: bits set: 1031/2049
| > xfree: NULL pointer given as argument
| > debug1: Calling cleanup 0x806b00c(0x0)
| 
| Can you narrow the config down a bit in terms of what may cause this,
| or get a stack trace?

How about this.  I modified all 486 instances of xfree() calls and
all 146 instances of buffer_free() calls to also have a debug3() call
before that call, (inside {} so it's handled right in conditionals),
saying what source file and line number was doing the calling.  This
was done on the same line so as not to distort line numbering from the
original.

Here's what my test runs now look like:

client:
=============================================================================
...
debug3: check_host_in_hostfile: match line 1
debug3: key.c#144 xfree
debug3: key.c#144 xfree
debug1: Host 'hamal' is known and matches the RSA host key.
debug1: Found key in /home/phil/.ssh/known_hosts:1
debug3: sshconnect.c#815 xfree
debug3: bufaux.c#138 xfree
debug1: bits set: 515/1024
debug3: kexgex.c#216 xfree
debug3: bufaux.c#128 xfree
debug3: bufaux.c#128 xfree
debug3: bufaux.c#128 xfree
debug3: bufaux.c#128 xfree
debug3: bufaux.c#128 xfree
debug3: kexgex.c#93 buffer_free
debug3: buffer.c#38 xfree
xfree: NULL pointer given as argument
debug1: Calling cleanup 0x806467c(0x0)
debug3: packet.c#336 buffer_free
debug3: buffer.c#38 xfree
debug3: packet.c#337 buffer_free
debug3: buffer.c#38 xfree
debug3: packet.c#338 buffer_free
debug3: buffer.c#38 xfree
debug3: packet.c#339 buffer_free
debug3: buffer.c#38 xfree
=============================================================================

server:
=============================================================================
...
debug3: kex.c#110 xfree
debug3: kex.c#111 xfree
debug3: packet.c#1266 xfree
debug3: packet.c#746 xfree
debug1: SSH2_MSG_KEX_DH_GEX_REQUEST received
debug1: SSH2_MSG_KEX_DH_GEX_GROUP sent
debug3: bufaux.c#128 xfree
debug3: bufaux.c#128 xfree
debug3: packet.c#1266 xfree
debug1: dh_gen_key: priv key bits set: 186/384
debug1: bits set: 1075/2049
debug1: expecting SSH2_MSG_KEX_DH_GEX_INIT
debug3: packet.c#1266 xfree
debug3: packet.c#746 xfree
debug3: bufaux.c#138 xfree
debug1: bits set: 1031/2049
debug3: kexgex.c#352 xfree
debug3: bufaux.c#128 xfree
debug3: bufaux.c#128 xfree
debug3: key.c#754 buffer_free
debug3: buffer.c#38 xfree
debug3: bufaux.c#128 xfree
debug3: bufaux.c#128 xfree
debug3: bufaux.c#128 xfree
debug3: bufaux.c#128 xfree
debug3: bufaux.c#128 xfree
debug3: kexgex.c#93 buffer_free
debug3: buffer.c#38 xfree
xfree: NULL pointer given as argument
debug1: Calling cleanup 0x806bd4c(0x0)
debug3: packet.c#336 buffer_free
debug3: buffer.c#38 xfree
debug3: packet.c#337 buffer_free
debug3: buffer.c#38 xfree
debug3: packet.c#338 buffer_free
debug3: buffer.c#38 xfree
debug3: packet.c#339 buffer_free
debug3: buffer.c#38 xfree
=============================================================================

The buffer_free() function is involved, so that's why I include it in
what debug3() would be tracking:
=============================================================================
void
buffer_free(Buffer *buffer)
{
        memset(buffer->buf, 0, buffer->alloc);
{debug3("buffer.c#38 xfree");xfree(buffer->buf);}
}
=============================================================================

So kexgex.c at line 93 looks like the culprit.  The code around there
looks like (with my change in place):
=============================================================================
static u_char *
kexgex_hash(
    char *client_version_string,
    char *server_version_string,
    char *ckexinit, int ckexinitlen,
    char *skexinit, int skexinitlen,
    u_char *serverhostkeyblob, int sbloblen,
    int min, int wantbits, int max, BIGNUM *prime, BIGNUM *gen,
    BIGNUM *client_dh_pub,
    BIGNUM *server_dh_pub,
    BIGNUM *shared_secret)
{
        Buffer b;
        static u_char digest[EVP_MAX_MD_SIZE];
        const EVP_MD *evp_md = EVP_sha1();
        EVP_MD_CTX md;

        buffer_init(&b);
        buffer_put_cstring(&b, client_version_string);
        buffer_put_cstring(&b, server_version_string);

        /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
        buffer_put_int(&b, ckexinitlen+1);
        buffer_put_char(&b, SSH2_MSG_KEXINIT);
        buffer_append(&b, ckexinit, ckexinitlen);
        buffer_put_int(&b, skexinitlen+1);
        buffer_put_char(&b, SSH2_MSG_KEXINIT);
        buffer_append(&b, skexinit, skexinitlen);

        buffer_put_string(&b, serverhostkeyblob, sbloblen);
        if (min == -1 || max == -1)
                buffer_put_int(&b, wantbits);
        else {
                buffer_put_int(&b, min);
                buffer_put_int(&b, wantbits);
                buffer_put_int(&b, max);
        }
        buffer_put_bignum2(&b, prime);
        buffer_put_bignum2(&b, gen);
        buffer_put_bignum2(&b, client_dh_pub);
        buffer_put_bignum2(&b, server_dh_pub);
        buffer_put_bignum2(&b, shared_secret);

#ifdef DEBUG_KEXDH
        buffer_dump(&b);
#endif
        EVP_DigestInit(&md, evp_md);
        EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
        EVP_DigestFinal(&md, digest, NULL);

{debug3("kexgex.c#93 buffer_free");buffer_free(&b);}
=============================================================================

-- 
-----------------------------------------------------------------
| Phil Howard - KA9WGN |   Dallas   | http://linuxhomepage.com/ |
| phil-nospam at ipal.net | Texas, USA | http://phil.ipal.org/     |
-----------------------------------------------------------------



More information about the openssh-unix-dev mailing list