CVE-2022-24807: Insufficient Information (NVD-CWE-noinfo)
value: net-snmp provides various tools relating to the Simple Network Management Protocol. Prior to version 5.9.2, a malformed OID in a SET request to `SNMP-VIEW-BASED-ACM-MIB::vacmAccessTable` can cause an out-of-bounds memory access. A user with read-write credentials can exploit the issue. Version 5.9.2 contains a patch. Users should use strong SNMPv3 credentials and avoid sharing the credentials. Those who must use SNMPv1 or SNMPv2c should use a complex community string and enhance the protection by restricting access to a given IP address range.

CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
Published: 2024-04-16T20:15Z
Repository: https://github.com/net-snmp/net-snmp
Language: C
Files changed: agent/mibgroup/agent/nsLogging.c, agent/mibgroup/agent/nsVacmAccessTable.c, agent/mibgroup/mibII/vacm_vars.c, agent/mibgroup/snmpv3/usmUser.c
Commit date: 2021-08-24 07:53:53 -0700
Commit message: CHANGES: snmpd: fix bounds checking in NET-SNMP-AGENT-MIB, NET-SNMP-VACM-MIB, SNMP-VIEW-BASED-ACM-MIB, SNMP-USER-BASED-SM-MIB

Reported by: Yu Zhang of VARAS@IIE, Nanyu Zhong of VARAS@IIE
Fixes by: Arista Networks

Diff: diff --git a/agent/mibgroup/agent/nsLogging.c b/agent/mibgroup/agent/nsLogging.c
index 9abdeb5bb7..7f4290490a 100644
--- a/agent/mibgroup/agent/nsLogging.c
+++ b/agent/mibgroup/agent/nsLogging.c
@@ -145,10 +145,12 @@ handle_nsLoggingTable(netsnmp_mib_handler *handler,
         for (request=requests; request; request=request->next) {
             if (request->processed != 0)
                 continue;
             logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request);
             table_info  =                netsnmp_extract_table_info(request);
+            if (!table_info || !table_info->indexes)
+                continue;
 
             switch (table_info->colnum) {
             case NSLOGGING_TYPE:
                 if (!logh) {
                     netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
@@ -199,10 +201,12 @@ handle_nsLoggingTable(netsnmp_mib_handler *handler,
             if ( request->status != 0 ) {
                 return SNMP_ERR_NOERROR;	/* Already got an error */
             }
             logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request);
             table_info  =                 netsnmp_extract_table_info(request);
+            if (!table_info || !table_info->indexes)
+                continue;
 
             switch (table_info->colnum) {
             case NSLOGGING_TYPE:
                 if ( request->requestvb->type != ASN_INTEGER ) {
                     netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
@@ -392,10 +396,12 @@ handle_nsLoggingTable(netsnmp_mib_handler *handler,
         for (request=requests; request; request=request->next) {
             if (request->processed != 0)
                 continue;
             logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request);
             table_info  =                 netsnmp_extract_table_info(request);
+            if (!table_info || !table_info->indexes)
+                continue;
 
             switch (table_info->colnum) {
             case NSLOGGING_TYPE:
                 /*
 		 * If we've been setting the type, and the request
diff --git a/agent/mibgroup/agent/nsVacmAccessTable.c b/agent/mibgroup/agent/nsVacmAccessTable.c
index cc61fce7e6..6c43210074 100644
--- a/agent/mibgroup/agent/nsVacmAccessTable.c
+++ b/agent/mibgroup/agent/nsVacmAccessTable.c
@@ -168,13 +168,17 @@ nsVacmAccessTable_handler(netsnmp_mib_handler *handler,
     case MODE_GET:
         for (request = requests; request; request = request->next) {
             entry = (struct vacm_accessEntry *)
                 netsnmp_extract_iterator_context(request);
             table_info = netsnmp_extract_table_info(request);
+            if (!table_info || !table_info->indexes)
+                continue;
 
             /* Extract the authType token from the list of indexes */
             idx = table_info->indexes->next_variable->next_variable->next_variable->next_variable;
+            if (idx->val_len >= sizeof(atype))
+                continue;
             memset(atype, 0, sizeof(atype));
             memcpy(atype, (char *)idx->val.string, idx->val_len);
             viewIdx = se_find_value_in_slist(VACM_VIEW_ENUM_NAME, atype);
             DEBUGMSGTL(("nsVacm", "GET %s (%d)\n", idx->val.string, viewIdx));
 
@@ -210,10 +214,12 @@ nsVacmAccessTable_handler(netsnmp_mib_handler *handler,
     case MODE_SET_RESERVE1:
         for (request = requests; request; request = request->next) {
             entry = (struct vacm_accessEntry *)
                 netsnmp_extract_iterator_context(request);
             table_info = netsnmp_extract_table_info(request);
+            if (!table_info || !table_info->indexes)
+                continue;
             ret = SNMP_ERR_NOERROR;
 
             switch (table_info->colnum) {
             case COLUMN_NSVACMCONTEXTMATCH:
                 ret = netsnmp_check_vb_int_range(request->requestvb, 1, 2);
@@ -245,10 +251,12 @@ nsVacmAccessTable_handler(netsnmp_mib_handler *handler,
 
                 /*
                  * Extract the authType token from the list of indexes
                  */
                 idx = table_info->indexes->next_variable->next_variable->next_variable->next_variable;
+                if (idx->val_len >= sizeof(atype))
+                    continue;
                 memset(atype, 0, sizeof(atype));
                 memcpy(atype, (char *)idx->val.string, idx->val_len);
                 viewIdx = se_find_value_in_slist(VACM_VIEW_ENUM_NAME, atype);
                 if ( viewIdx < 0 ) {
                     ret = SNMP_ERR_NOCREATION;
@@ -292,12 +300,14 @@ nsVacmAccessTable_handler(netsnmp_mib_handler *handler,
                          idx = table_info->indexes; gName = (char*)idx->val.string;
                          idx = idx->next_variable;  cPrefix = (char*)idx->val.string;
                          idx = idx->next_variable;  model = *idx->val.integer;
                          idx = idx->next_variable;  level = *idx->val.integer;
                          entry = vacm_createAccessEntry( gName, cPrefix, model, level );
-                         entry->storageType = ST_NONVOLATILE;
-                         netsnmp_insert_iterator_context(request, (void*)entry);
+                         if (entry) {
+                             entry->storageType = ST_NONVOLATILE;
+                             netsnmp_insert_iterator_context(request, (void*)entry);
+                         }
                     }
                 }
             }
         }
         break;
@@ -319,10 +329,12 @@ nsVacmAccessTable_handler(netsnmp_mib_handler *handler,
             if ( !entry )
                 continue;  /* Shouldn't happen */
 
             /* Extract the authType token from the list of indexes */
             idx = table_info->indexes->next_variable->next_variable->next_variable->next_variable;
+            if (idx->val_len >= sizeof(atype))
+                continue;
             memset(atype, 0, sizeof(atype));
             memcpy(atype, (char *)idx->val.string, idx->val_len);
             viewIdx = se_find_value_in_slist(VACM_VIEW_ENUM_NAME, atype);
             if (viewIdx < 0)
                     continue;
diff --git a/agent/mibgroup/mibII/vacm_vars.c b/agent/mibgroup/mibII/vacm_vars.c
index 469a1eba59..62c9a3d051 100644
--- a/agent/mibgroup/mibII/vacm_vars.c
+++ b/agent/mibgroup/mibII/vacm_vars.c
@@ -995,10 +995,13 @@ access_parse_oid(oid * oidIndex, size_t oidLen,
      */
     if ((oidLen <= 0) || (!oidIndex)) {
         return 1;
     }
     groupNameL = oidIndex[0];
+    if ((groupNameL + 1) > (int) oidLen) {
+        return 1;
+    }
     contextPrefixL = oidIndex[groupNameL + 1];  /* the initial name length */
     if ((int) oidLen != groupNameL + contextPrefixL + 4) {
         return 1;
     }
 
diff --git a/agent/mibgroup/snmpv3/usmUser.c b/agent/mibgroup/snmpv3/usmUser.c
index 0f52aaba49..0edea53cfb 100644
--- a/agent/mibgroup/snmpv3/usmUser.c
+++ b/agent/mibgroup/snmpv3/usmUser.c
@@ -1503,12 +1503,10 @@ write_usmUserStatus(int action,
         if (uptr != NULL) {
             if (long_ret == RS_CREATEANDGO || long_ret == RS_ACTIVE) {
                 if (usmStatusCheck(uptr)) {
                     uptr->userStatus = RS_ACTIVE;
                 } else {
-                    SNMP_FREE(engineID);
-                    SNMP_FREE(newName);
                     return SNMP_ERR_INCONSISTENTVALUE;
                 }
             } else if (long_ret == RS_CREATEANDWAIT) {
                 if (usmStatusCheck(uptr)) {
                     uptr->userStatus = RS_NOTINSERVICE;

Vulnerable code:                          entry->storageType = ST_NONVOLATILE;
                         netsnmp_insert_iterator_context(request, (void*)entry);
                    SNMP_FREE(engineID);
                    SNMP_FREE(newName);
Fixed code:             if (!table_info || !table_info->indexes)
                continue;
            if (!table_info || !table_info->indexes)
                continue;
            if (!table_info || !table_info->indexes)
                continue;
            if (!table_info || !table_info->indexes)
                continue;
            if (idx->val_len >= sizeof(atype))
                continue;
            if (!table_info || !table_info->indexes)
                continue;
                if (idx->val_len >= sizeof(atype))
                    continue;
                         if (entry) {
                             entry->storageType = ST_NONVOLATILE;
                             netsnmp_insert_iterator_context(request, (void*)entry);
                         }
            if (idx->val_len >= sizeof(atype))
                continue;
    if ((groupNameL + 1) > (int) oidLen) {
        return 1;
    }