diff options
author | 2020-09-29 14:22:50 +0000 | |
---|---|---|
committer | 2020-09-29 14:22:50 +0000 | |
commit | e5554ca0ceee6b791e1d61a76e50d571a38fc2f1 (patch) | |
tree | 808383d6fcbd5677059a452fe1b9781023a2af65 | |
parent | Add support for the PCA9546 I2C switch to pcamux(4). In comparison to (diff) | |
download | wireguard-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.c | 16 |
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]); } |