From b3f9557f520802ee022cea47c024d08fd481eaca Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 20 Dec 2016 12:42:47 -0800 Subject: [PATCH] kex: acknowledge error code from libssh2_dh_key_pair() Fixes a segfault using ssh-agent on Windows This commit fixes a segfault seen dereferencing a null pointer on Windows when using ssh-agent. The problem ended up being that errors weren't being communicated all the way through, causing null pointers to be used when functions should have bailed out sooner. The `_libssh2_dh_key_pair` function for WinCNG was modified to propagate errors, and then the two callsites in kex.c of `diffie_hellman_sha{1,256}` were updated to recognize this error and bail out. Fixes #162 Closes #163 --- src/kex.c | 12 ++++++++---- src/wincng.c | 6 ++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/kex.c b/src/kex.c index 8df34172..5e761e39 100644 --- a/src/kex.c +++ b/src/kex.c @@ -133,8 +133,10 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session, memset(&exchange_state->req_state, 0, sizeof(packet_require_state_t)); /* Generate x and e */ - libssh2_dh_key_pair(&exchange_state->x, exchange_state->e, g, p, - group_order, exchange_state->ctx); + rc = libssh2_dh_key_pair(&exchange_state->x, exchange_state->e, g, p, + group_order, exchange_state->ctx); + if (rc) + goto clean_exit; /* Send KEX init */ /* packet_type(1) + String Length(4) + leading 0(1) */ @@ -757,8 +759,10 @@ static int diffie_hellman_sha256(LIBSSH2_SESSION *session, memset(&exchange_state->req_state, 0, sizeof(packet_require_state_t)); /* Generate x and e */ - libssh2_dh_key_pair(&exchange_state->x, exchange_state->e, g, p, - group_order, exchange_state->ctx); + rc = libssh2_dh_key_pair(&exchange_state->x, exchange_state->e, g, p, + group_order, exchange_state->ctx); + if (rc) + goto clean_exit; /* Send KEX init */ /* packet_type(1) + String Length(4) + leading 0(1) */ diff --git a/src/wincng.c b/src/wincng.c index 6b0a7a90..6275c3e7 100755 --- a/src/wincng.c +++ b/src/wincng.c @@ -2075,8 +2075,10 @@ _libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public, _libssh2_bn *g, _libssh2_bn *p, int group_order) { /* Generate x and e */ - _libssh2_wincng_bignum_rand(*dhctx, group_order * 8 - 1, 0, -1); - _libssh2_wincng_bignum_mod_exp(public, g, *dhctx, p); + if (_libssh2_wincng_bignum_rand(*dhctx, group_order * 8 - 1, 0, -1)) + return -1; + if (_libssh2_wincng_bignum_mod_exp(public, g, *dhctx, p)) + return -1; return 0; }