'How to check if cache is valid in net-snmp agent?

I have agent created with mib2c.mfd.conf configuration. Agent crush because baby step irreversible_commit is called after cache free, so rowreq_ctx points to invalid memory.

I was calling snmpset every second. After cache timeout or if I compile without NETSNMP_CACHE_DONT_INVALIDATE_ON_SET it broke on rowreq_ctx->...

I don't think that I will be able to change code of netsnmp library which containts netsnmp_container_table_row_extract that return pointer to freed memory. So I wanted to check cache validity myself, but I don't know how to do it from arguments that I have in _mfd_mseDpuConfigActivationTable_irreversible_commit function.

UPDATE: For now I added global variable for *_interface.c that is set in _cache_load and unset in _cache_free. In every function in *_interface.c that use netsnmp_container_table_row_extract I'm, checking this variable if is set.

/*----------------------------------------------------------------------
 *
 * SET: irreversible commit
 *
 *---------------------------------------------------------------------*/
/**
 * @internal
 * commit irreversible actions
 */
int _mfd_mseDpuConfigActivationTable_irreversible_commit(netsnmp_mib_handler *handler,
                                                         netsnmp_handler_registration *reginfo,
                                                         netsnmp_agent_request_info *agtreq_info,
                                                         netsnmp_request_info *requests)
{
    mseDpuConfigActivationTable_rowreq_ctx *rowreq_ctx = (mseDpuConfigActivationTable_rowreq_ctx *)
        netsnmp_container_table_row_extract(requests);

    DEBUGMSGTL(("internal:mseDpuConfigActivationTable:_mfd_mseDpuConfigActivationTable_irreversible:commit", "called\n"));
    (void)handler;
    (void)reginfo;
    (void)agtreq_info;
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * check for and handle row creation/deletion
     * and update column exist flags...
     */
    // ==24103==ERROR: AddressSanitizer: heap-use-after-free on address
    if (rowreq_ctx->rowreq_flags & MFD_ROW_DELETED)
    {
        if (!(rowreq_ctx->rowreq_flags & MFD_ROW_CREATED))
        {
            CONTAINER_REMOVE(mseDpuConfigActivationTable_if_ctx.container, rowreq_ctx);
        }
    }
    else
    {
        if (rowreq_ctx->column_set_flags)
        {            DEBUGMSGTL(("internal:mseDpuConfigActivationTable:_mfd_irreversible_commit",
                        "updating exists (0x%x) w/set (0x%x) = 0x%x\n",
                        rowreq_ctx->column_exists_flags,
                        rowreq_ctx->column_set_flags,
                        (rowreq_ctx->column_exists_flags |
                         rowreq_ctx->column_set_flags)));
            rowreq_ctx->column_exists_flags |=
                rowreq_ctx->column_set_flags;
            rowreq_ctx->column_set_flags = 0;
        }
    }

    return SNMP_ERR_NOERROR;
} /* _mfd_mseDpuConfigActivationTable_irreversible_commit */


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source