From: Ralf Lici <[email protected]> If installing a DCO key succeeds, always record the slot in the corresponding key_state. The installed-key counter only tracks whether the number of kernel slots grew, but a successful KEY_NEW still means that this key_state is associated with the selected DCO slot.
Also replace DCO key-state assertions in dco_update_keys() with error returns. This preserves the invariant checks but lets the existing caller restart the connection instead of aborting the process if userspace ever detects inconsistent DCO key state. Github: https://github.com/OpenVPN/openvpn-private-issues/issues/143 Change-Id: I4d0887839b4a13a92e92250d1b315dec949698f3 Signed-off-by: Ralf Lici <[email protected]> Acked-by: Antonio Quartulli <[email protected]> Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1795 --- This change was reviewed on Gerrit and approved by at least one developer. I request to merge it to master. Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1795 This mail reflects revision 3 of this Change. Acked-by according to Gerrit (reflected above): Antonio Quartulli <[email protected]> diff --git a/src/openvpn/dco.c b/src/openvpn/dco.c index e944547..2584368 100644 --- a/src/openvpn/dco.c +++ b/src/openvpn/dco.c @@ -73,9 +73,12 @@ int ret = dco_new_key(multi->dco, multi->dco_peer_id, ks->key_id, slot, encrypt_key, encrypt_iv, decrypt_key, decrypt_iv, ciphername, epoch); - if ((ret == 0) && (multi->dco_keys_installed < 2)) + if (ret == 0) { - multi->dco_keys_installed++; + if (multi->dco_keys_installed < 2) + { + multi->dco_keys_installed++; + } ks->dco_status = (slot == OVPN_KEY_SLOT_PRIMARY) ? DCO_INSTALLED_PRIMARY : DCO_INSTALLED_SECONDARY; } @@ -166,7 +169,13 @@ /* if we have a primary key, it must have been installed already (keys * are installed upon generation in the TLS code) */ - ASSERT(primary->dco_status != DCO_NOT_INSTALLED); + if (primary->dco_status == DCO_NOT_INSTALLED) + { + msg(D_DCO, "DCO key state mismatch: selected primary key is not installed " + "(peer_id=%d, key_id=%d, dco_keys_installed=%d)", + multi->dco_peer_id, primary->key_id, multi->dco_keys_installed); + return false; + } struct key_state *secondary = dco_get_secondary_key(multi, primary); /* if the current primary key was installed as secondary in DCO, @@ -190,6 +199,14 @@ primary->key_id); } + if (secondary && secondary->dco_status != DCO_INSTALLED_PRIMARY) + { + msg(D_DCO, "DCO key state mismatch: expected old primary key is not installed as DCO primary before swap " + "(peer_id=%d, new_primary_key_id=%d, old_primary_key_id=%d, old_primary_dco_status=%d, dco_keys_installed=%d)", + multi->dco_peer_id, primary->key_id, secondary->key_id, secondary->dco_status, multi->dco_keys_installed); + return false; + } + int ret = dco_swap_keys(dco, multi->dco_peer_id); if (ret < 0) { @@ -200,7 +217,6 @@ primary->dco_status = DCO_INSTALLED_PRIMARY; if (secondary) { - ASSERT(secondary->dco_status == DCO_INSTALLED_PRIMARY); secondary->dco_status = DCO_INSTALLED_SECONDARY; } } _______________________________________________ Openvpn-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openvpn-devel
