------------------------------------------------------------ revno: 11749 revision-id: squid3@treenet.co.nz-20130128042817-1bkiwsq6vqo6ed70 parent: squid3@treenet.co.nz-20130128042732-511lvfmjk733z9bw author: Tomas Hozza committer: Amos Jeffries branch nick: 3.2 timestamp: Sun 2013-01-27 21:28:17 -0700 message: Fix various issues in snmplib * Memory leaks in OID management * NULL pointer dereference on OID tree creation * Ensure buffer terminations on OID data copy * Better file handle management Detected by Coverity Scan. Issues 740480, 740357, 740429, 443111, 740479, 740500 ------------------------------------------------------------ # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: squid3@treenet.co.nz-20130128042817-1bkiwsq6vqo6ed70 # target_branch: http://bzr.squid-cache.org/bzr/squid3/branches\ # /SQUID_3_2 # testament_sha1: 822154d1c5ccc9cb74e22df54a39da38934c17d7 # timestamp: 2013-01-28 04:35:44 +0000 # source_branch: http://bzr.squid-cache.org/bzr/squid3/branches\ # /SQUID_3_2 # base_revision_id: squid3@treenet.co.nz-20130128042732-\ # 511lvfmjk733z9bw # # Begin patch === modified file 'snmplib/parse.c' --- snmplib/parse.c 2012-02-05 06:09:46 +0000 +++ snmplib/parse.c 2013-01-28 04:28:17 +0000 @@ -408,7 +408,7 @@ np->enums = NULL; /* so we don't free them later */ if (root->child_list == NULL) { root->child_list = tp; - } else { + } else if (peer) { peer->next_peer = tp; } peer = tp; @@ -630,6 +630,16 @@ xfree((char *) np); } +static void +free_node_list(struct node *nl) +{ + while (nl) { + struct node *t = nl->next; + free_node(nl); + nl = t; + } +} + /* * Parse an entry of the form: * label OBJECT IDENTIFIER ::= { parent 2 } @@ -662,9 +672,9 @@ op++, nop++) { /* every node must have parent's name and child's name or number */ if (op->label && (nop->label || (nop->subid != -1))) { - strcpy(np->parent, op->label); + strncpy(np->parent, op->label, sizeof(np->parent) - 1); if (nop->label) - strcpy(np->label, nop->label); + strncpy(np->label, nop->label, sizeof(np->label) - 1); if (nop->subid != -1) np->subid = nop->subid; np->type = 0; @@ -685,8 +695,8 @@ */ if (count == (length - 2)) { if (op->label) { - strcpy(np->parent, op->label); - strcpy(np->label, name); + strncpy(np->parent, op->label, sizeof(np->parent)); + strncpy(np->label, name, sizeof(np->label)); if (nop->subid != -1) np->subid = nop->subid; else @@ -695,12 +705,14 @@ free_node(np); if (oldnp) oldnp->next = NULL; - else + else { + free_node_list(root); // we need to clear the newly allocated list return NULL; + } } } else { print_error("Missing end of oid", (char *) NULL, type); - free_node(np); /* the last node allocated wasn't used */ + free_node_list(root); // we need to clear the newly allocated list if (oldnp) oldnp->next = NULL; return NULL; @@ -950,9 +962,12 @@ length = getoid(fp, SubOid, 32); if (length > 1 && length <= 32) { /* just take the last pair in the oid list */ - if (SubOid[length - 2].label) + if (SubOid[length - 2].label) { strncpy(np->parent, SubOid[length - 2].label, 64); - strcpy(np->label, name); + np->parent[63] = '\0'; + } + strncpy(np->label, name, sizeof(np->label)); + np->label[sizeof(np->label) - 1] = '\0'; if (SubOid[length - 1].subid != -1) np->subid = SubOid[length - 1].subid; else @@ -995,6 +1010,7 @@ return root; } print_error(token, "is a reserved word", type); + free_node_list(root); return NULL; } strncpy(name, token, 64); @@ -1011,6 +1027,7 @@ np->next = parse_objecttype(fp, name); if (np->next == NULL) { print_error("Bad parse of objecttype", (char *) NULL, type); + free_node_list(root); return NULL; } } @@ -1029,6 +1046,7 @@ np->next = parse_objectid(fp, name); if (np->next == NULL) { print_error("Bad parse of object type", (char *) NULL, type); + free_node_list(root); return NULL; } } @@ -1041,6 +1059,7 @@ break; } else { print_error("Bad operator", (char *) NULL, type); + free_node_list(root); return NULL; } } @@ -1081,18 +1100,20 @@ strlen("DUMMY"))); if (!p) { snmplib_debug(0, "Bad MIB version or tag missing, install original!\n"); + fclose(fp); return NULL; } if (!strcmp(mbuf, "DUMMY")) { snmplib_debug(0, "You need to update your MIB!\n"); + fclose(fp); return NULL; } nodes = parse(fp); + fclose(fp); if (!nodes) { snmplib_debug(0, "Mib table is bad. Exiting\n"); return NULL; } tree = build_tree(nodes); - fclose(fp); return (tree); } === modified file 'snmplib/snmp_vars.c' --- snmplib/snmp_vars.c 2012-02-05 06:09:46 +0000 +++ snmplib/snmp_vars.c 2013-01-28 04:28:17 +0000 @@ -377,6 +377,7 @@ u_char *DataPtr; int DataLen; oid TmpBuf[MAX_NAME_LEN]; + memset(TmpBuf, 0, MAX_NAME_LEN * sizeof(*TmpBuf)); int AllVarLen = *BufLen; int ThisVarLen = 0;