From 3b099e9403c61d184d325c7b5c7fde30a572cf5c Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Tue, 20 Feb 2024 15:58:20 +0100 Subject: [PATCH] Fix potential double free of ratchet identity key libsignal does this properly, so there wouldn't be a real double free, but it will `abort()`. Instead of destroying the identity key on disconnect, already destroy it after it has been put into the libsignal 'ratchet identity key pair'. In the case where the key pair is initially generated, the public and private parts are only `ref()`'ed once in [0]. In the case where the key pair is read from the disk, the public and private parts are `ref()`'ed twice, first when decoded in [1] resp. [2] and a second time in [3]. When `omemo_on_disconnect()` is called we were `unref()`'ing the parts twice, before this patch. First in [4], a second time in [5] resp. [6]. Now we do the second `unref()` already when loading. [0] `signal_protocol_key_helper_generate_identity_key_pair()` [1] `curve_decode_point()` [2] `curve_decode_private_point()` [3] `ratchet_identity_key_pair_create()` [4] `ratchet_identity_key_pair_destroy()` [5] `ec_private_key_destroy()` [6] `ec_public_key_destroy()` Signed-off-by: Steffen Jaeckel --- src/omemo/omemo.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/omemo/omemo.c b/src/omemo/omemo.c index da0bfc53..5155adac 100644 --- a/src/omemo/omemo.c +++ b/src/omemo/omemo.c @@ -271,11 +271,7 @@ omemo_on_disconnect(void) free_keyfile(&omemo_ctx.identity); signal_protocol_store_context_destroy(omemo_ctx.store); - ec_public_key* pub = ratchet_identity_key_pair_get_public(omemo_ctx.identity_key_pair); - ec_private_key* priv = ratchet_identity_key_pair_get_private(omemo_ctx.identity_key_pair); ratchet_identity_key_pair_destroy((signal_type_base*)omemo_ctx.identity_key_pair); - ec_private_key_destroy((signal_type_base*)priv); - ec_public_key_destroy((signal_type_base*)pub); signal_context_destroy(omemo_ctx.signal); memset(&omemo_ctx, 0, sizeof(omemo_ctx)); @@ -1470,6 +1466,8 @@ _load_identity(void) ec_private_key* private_key; curve_decode_private_point(&private_key, identity_key_private, identity_key_private_len, omemo_ctx.signal); ratchet_identity_key_pair_create(&omemo_ctx.identity_key_pair, public_key, private_key); + ec_private_key_destroy((signal_type_base*)private_key); + ec_public_key_destroy((signal_type_base*)public_key); char** keys = NULL; int i;