When a connection is reset while we still have an outstanding request,
the connection from the request to the rest of the structure is removed,
so we don't send any old data over the new connection.

However, the current code dereferences axc at a couple of places before
we check it for NULL.

Found the hard way by Mischa Peters while stress testing agentx support
for vmd.

OK?

martijn@

Index: agentx.c
===================================================================
RCS file: /cvs/src/lib/libagentx/agentx.c,v
retrieving revision 1.16
diff -u -p -r1.16 agentx.c
--- agentx.c    29 Aug 2022 12:17:24 -0000      1.16
+++ agentx.c    13 Sep 2022 09:51:02 -0000
@@ -2575,8 +2575,8 @@ static void
 agentx_get_finalize(struct agentx_get *axg)
 {
        struct agentx_context *axc = axg->axg_axc;
-       struct agentx_session *axs = axc->axc_axs;
-       struct agentx *ax = axs->axs_ax;
+       struct agentx_session *axs;
+       struct agentx *ax;
        size_t i, j, nvarbind = 0;
        uint16_t error = 0, index = 0;
        struct ax_varbind *vbl;
@@ -2591,11 +2591,14 @@ agentx_get_finalize(struct agentx_get *a
                }
        }
 
-       if (axg->axg_axc == NULL) {
+       if (axc == NULL) {
                agentx_get_free(axg);
                return;
        }
 
+       axs = axc->axc_axs;
+       ax = axs->axs_ax;
+
        if ((vbl = calloc(nvarbind, sizeof(*vbl))) == NULL) {
                agentx_log_axg_warn(axg, "Couldn't parse request");
                agentx_get_free(axg);
@@ -2655,12 +2658,14 @@ agentx_get_free(struct agentx_get *axg)
 {
        struct agentx_varbind *axv;
        struct agentx_object *axo;
-       struct agentx *ax = axg->axg_axc->axc_axs->axs_ax;
+       struct agentx *ax;
        struct agentx_varbind_index *index;
        size_t i, j;
 
-       if (axg->axg_axc != NULL)
+       if (axg->axg_axc != NULL) {
+               ax = axg->axg_axc->axc_axs->axs_ax;
                TAILQ_REMOVE(&(ax->ax_getreqs), axg, axg_ax_getreqs);
+       }
 
        for (i = 0; i < axg->axg_nvarbind; i++) {
                axv = &(axg->axg_varbind[i]);
@@ -2701,6 +2706,11 @@ agentx_varbind_start(struct agentx_varbi
                agentx_log_axg_fatalx(axv->axv_axg,
                    "%s: axv_initialized not set", __func__);
 #endif
+
+       if (axc == NULL) {
+               agentx_varbind_error_type(axv, AX_PDU_ERROR_PROCESSINGERROR, 1);
+               return;
+       }
 
        bcopy(&(axv->axv_vb.avb_oid), &(axo_search.axo_oid),
            sizeof(axo_search.axo_oid));

Reply via email to