components/net-snmp-57/patches/059.21544351.snmp_api.patch
changeset 5867 445e2cf1c845
parent 4755 dc5e4f992365
equal deleted inserted replaced
5866:683c5c035a79 5867:445e2cf1c845
       
     1 This patch fixes a security issue where snmp_pdu_parse() function 
       
     2 could leave incompletely parsed varBind variables in the list of  
       
     3 variables. A remote, unauthenticated attacker could exploit this 
       
     4 flaw to cause a crash or, potentially, execute arbitrary code.
       
     5 The vulnerability is fixed in the upsream and below is the link 
       
     6 to the upstream bug.
       
     7 https://sourceforge.net/p/net-snmp/bugs/2615/ 
       
     8 
       
     9 --- a/snmplib/snmp_api.c	Mon Aug  3 03:34:05 2015
       
    10 +++ b/snmplib/snmp_api.c	Mon Aug  3 03:31:01 2015
       
    11 @@ -4270,10 +4270,9 @@
       
    12      u_char          type;
       
    13      u_char          msg_type;
       
    14      u_char         *var_val;
       
    15 -    int             badtype = 0;
       
    16      size_t          len;
       
    17      size_t          four;
       
    18 -    netsnmp_variable_list *vp = NULL;
       
    19 +    netsnmp_variable_list *vp = NULL, *vplast = NULL;
       
    20      oid             objid[MAX_OID_LEN];
       
    21  
       
    22      /*
       
    23 @@ -4486,38 +4486,24 @@
       
    24                                (ASN_SEQUENCE | ASN_CONSTRUCTOR),
       
    25                                "varbinds");
       
    26      if (data == NULL)
       
    27 -        return -1;
       
    28 +        goto fail;
       
    29  
       
    30      /*
       
    31       * get each varBind sequence 
       
    32       */
       
    33      while ((int) *length > 0) {
       
    34 -        netsnmp_variable_list *vptemp;
       
    35 -        vptemp = (netsnmp_variable_list *) malloc(sizeof(*vptemp));
       
    36 -        if (NULL == vptemp) {
       
    37 -            return -1;
       
    38 -        }
       
    39 -        if (NULL == vp) {
       
    40 -            pdu->variables = vptemp;
       
    41 -        } else {
       
    42 -            vp->next_variable = vptemp;
       
    43 -        }
       
    44 -        vp = vptemp;
       
    45 -
       
    46 -        vp->next_variable = NULL;
       
    47 -        vp->val.string = NULL;
       
    48 +        vp = SNMP_MALLOC_TYPEDEF(netsnmp_variable_list);
       
    49 +        if (NULL == vp)
       
    50 +            goto fail;
       
    51          vp->name_length = MAX_OID_LEN;
       
    52 -        vp->name = NULL;
       
    53 -        vp->index = 0;
       
    54 -        vp->data = NULL;
       
    55 -        vp->dataFreeHook = NULL;
       
    56 +        vp->type = 0;
       
    57          DEBUGDUMPSECTION("recv", "VarBind");
       
    58          data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type,
       
    59                                   &vp->val_len, &var_val, length);
       
    60          if (data == NULL)
       
    61 -            return -1;
       
    62 +            goto fail;
       
    63          if (snmp_set_var_objid(vp, objid, vp->name_length))
       
    64 -            return -1;
       
    65 +            goto fail;
       
    66  
       
    67          len = MAX_PACKET_LENGTH;
       
    68          DEBUGDUMPHEADER("recv", "Value");
       
    69 @@ -4504,7 +4488,7 @@
       
    70                  vp->val.string = (u_char *) malloc(vp->val_len);
       
    71              }
       
    72              if (vp->val.string == NULL) {
       
    73 -                return -1;
       
    74 +                goto fail;
       
    75              }
       
    76              asn_parse_string(var_val, &len, &vp->type, vp->val.string,
       
    77                               &vp->val_len);
       
    78 @@ -4515,7 +4499,7 @@
       
    79              vp->val_len *= sizeof(oid);
       
    80              vp->val.objid = (oid *) malloc(vp->val_len);
       
    81              if (vp->val.objid == NULL) {
       
    82 -                return -1;
       
    83 +                goto fail;
       
    84              }
       
    85              memmove(vp->val.objid, objid, vp->val_len);
       
    86              break;
       
    87 @@ -4527,7 +4511,7 @@
       
    88          case ASN_BIT_STR:
       
    89              vp->val.bitstring = (u_char *) malloc(vp->val_len);
       
    90              if (vp->val.bitstring == NULL) {
       
    91 -                return -1;
       
    92 +                goto fail;
       
    93              }
       
    94              asn_parse_bitstring(var_val, &len, &vp->type,
       
    95                                  vp->val.bitstring, &vp->val_len);
       
    96 @@ -4534,12 +4518,25 @@
       
    97              break;
       
    98          default:
       
    99              snmp_log(LOG_ERR, "bad type returned (%x)\n", vp->type);
       
   100 -            badtype = -1;
       
   101 +            goto fail;
       
   102              break;
       
   103          }
       
   104          DEBUGINDENTADD(-4);
       
   105 +        if (NULL == vplast) {
       
   106 +            pdu->variables = vp;
       
   107 +        } else {
       
   108 +            vplast->next_variable = vp;
       
   109 +        }
       
   110 +        vplast = vp;
       
   111 +        vp = NULL;
       
   112      }
       
   113 -    return badtype;
       
   114 +    return 0;
       
   115 +    fail:
       
   116 +      DEBUGMSGTL(("recv", "error while parsing VarBindList\n"));
       
   117 +      /** if we were parsing a var, remove it from the pdu and free it */
       
   118 +      if (vp)
       
   119 +        snmp_free_var(vp);
       
   120 +      return -1;
       
   121  }
       
   122  
       
   123  /*