------------------------------------------------------------ revno: 12430 revision-id: squid3@treenet.co.nz-20121230073150-88eirnv3sxkkaa0t parent: squid3@treenet.co.nz-20121230073040-xqcllwj2bsao11nd author: Tomas Hozza committer: Amos Jeffries branch nick: 3.3 timestamp: Sun 2012-12-30 00:31:50 -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-20121230073150-88eirnv3sxkkaa0t # target_branch: http://bzr.squid-cache.org/bzr/squid3/3.3 # testament_sha1: eb8f87ea91731d2032eabde8b3874caa5ab7e3de # timestamp: 2012-12-30 07:54:10 +0000 # source_branch: http://bzr.squid-cache.org/bzr/squid3/3.3 # base_revision_id: squid3@treenet.co.nz-20121230073040-\ # xqcllwj2bsao11nd # # Begin patch === modified file 'snmplib/parse.c' --- snmplib/parse.c 2012-08-28 13:00:30 +0000 +++ snmplib/parse.c 2012-12-30 07:31:50 +0000 @@ -405,7 +405,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; @@ -625,6 +625,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 } @@ -657,9 +667,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; @@ -680,8 +690,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 @@ -690,12 +700,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; @@ -945,9 +957,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 @@ -989,6 +1004,7 @@ return root; } print_error(token, "is a reserved word", type); + free_node_list(root); return NULL; } strncpy(name, token, 64); @@ -1005,6 +1021,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; } } @@ -1023,6 +1040,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; } } @@ -1035,6 +1053,7 @@ break; } else { print_error("Bad operator", (char *) NULL, type); + free_node_list(root); return NULL; } } @@ -1075,18 +1094,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-08-28 13:00:30 +0000 +++ snmplib/snmp_vars.c 2012-12-30 07:31:50 +0000 @@ -373,6 +373,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;