summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormartijn <martijn@openbsd.org>2020-09-29 14:22:50 +0000
committermartijn <martijn@openbsd.org>2020-09-29 14:22:50 +0000
commite5554ca0ceee6b791e1d61a76e50d571a38fc2f1 (patch)
tree808383d6fcbd5677059a452fe1b9781023a2af65
parentAdd support for the PCA9546 I2C switch to pcamux(4). In comparison to (diff)
downloadwireguard-openbsd-e5554ca0ceee6b791e1d61a76e50d571a38fc2f1.tar.xz
wireguard-openbsd-e5554ca0ceee6b791e1d61a76e50d571a38fc2f1.zip
Fix 3 bugs:
1) Don't declare subagentx_index SA_DSTATE_CLOSE until all subfunctions are done with it. This prevents premature freeing of the object. 2) In subagentx_index_free make sure that if an subagentx_object moves out from under us we correct for this. 3) Don't call subagentx_index_free_finalize if sai_cstate is not SA_CSTATE_CLOSE. The first and last can be triggered when calling free while we're disconnected from the agentx master. The second one can only be triggered with when the freed object is not the last one in the list.
-rw-r--r--lib/libagentx/subagentx.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/lib/libagentx/subagentx.c b/lib/libagentx/subagentx.c
index 6c392a1cb63..ccb9684196b 100644
--- a/lib/libagentx/subagentx.c
+++ b/lib/libagentx/subagentx.c
@@ -1729,6 +1729,7 @@ void
subagentx_index_free(struct subagentx_index *sai)
{
size_t i;
+ struct subagentx_object *sao;
if (sai == NULL)
return;
@@ -1737,14 +1738,18 @@ subagentx_index_free(struct subagentx_index *sai)
subagentx_log_sac_fatalx(sai->sai_sar->sar_sac,
"%s: double free", __func__);
- sai->sai_dstate = SA_DSTATE_CLOSE;
-
/* TODO Do a range_subid unregister before freeing */
for (i = 0; i < sai->sai_objectlen; i++) {
- if (sai->sai_object[i]->sao_dstate != SA_DSTATE_CLOSE)
- subagentx_object_free(sai->sai_object[i]);
+ sao = sai->sai_object[i];
+ if (sao->sao_dstate != SA_DSTATE_CLOSE) {
+ subagentx_object_free(sao);
+ if (sai->sai_object[i] != sao)
+ i--;
+ }
}
+ sai->sai_dstate = SA_DSTATE_CLOSE;
+
if (sai->sai_cstate == SA_CSTATE_OPEN)
(void) subagentx_index_close(sai);
else if (sai->sai_cstate == SA_CSTATE_CLOSE)
@@ -2415,7 +2420,8 @@ subagentx_object_free_finalize(struct subagentx_object *sao)
"%s: object not found in index", __func__);
#endif
sao->sao_index[i]->sai_objectlen--;
- if (sao->sao_index[i]->sai_dstate == SA_DSTATE_CLOSE)
+ if (sao->sao_index[i]->sai_dstate == SA_DSTATE_CLOSE &&
+ sao->sao_index[i]->sai_cstate == SA_CSTATE_CLOSE)
subagentx_index_free_finalize(sao->sao_index[i]);
}