In
a8d3c90feca5, some memory leaks were fixed when a TLV is present
multiple times. There were other occurrences in LLDP, CDP and EDP
handling. We ensure we free before overwriting with the new TLVs.
Fix #436
lldpd (1.0.9)
* Fix:
+ Do not use interface alias if we set it ourselves.
+ + More memory leak fixes on duplicate TLVs in LLDP, CDP and EDP
+ (related to CVE-2020-27827).
* Changes:
+ Display port status with "show interfaces".
+ Do not display "age" and "via" when using "show interfaces".
}
switch (tlv_type) {
case CDP_TLV_CHASSIS:
+ free(chassis->c_name);
if ((chassis->c_name = (char *)calloc(1, tlv_len + 1)) == NULL) {
log_warn("cdp", "unable to allocate memory for chassis name");
goto malformed;
}
PEEK_BYTES(chassis->c_name, tlv_len);
chassis->c_id_subtype = LLDP_CHASSISID_SUBTYPE_LOCAL;
- if ((chassis->c_id = (char *)malloc(tlv_len)) == NULL) {
+ free(chassis->c_id);
+ if ((chassis->c_id = (char *)malloc(tlv_len)) == NULL) {
log_warn("cdp", "unable to allocate memory for chassis ID");
goto malformed;
}
log_warn("cdp", "too short port description received");
goto malformed;
}
+ free(port->p_descr);
if ((port->p_descr = (char *)calloc(1, tlv_len + 1)) == NULL) {
log_warn("cdp", "unable to allocate memory for port description");
goto malformed;
}
PEEK_BYTES(port->p_descr, tlv_len);
port->p_id_subtype = LLDP_PORTID_SUBTYPE_IFNAME;
+ free(port->p_id);
if ((port->p_id = (char *)calloc(1, tlv_len)) == NULL) {
log_warn("cdp", "unable to allocate memory for port ID");
goto malformed;
}
break;
case EDP_TLV_DISPLAY:
+ free(chassis->c_name);
if ((chassis->c_name = (char *)calloc(1, tlv_len + 1)) == NULL) {
log_warn("edp", "unable to allocate memory for chassis "
"name");
goto malformed;
}
PEEK_BYTES(b, tlv_size);
- if (tlv_type == LLDP_TLV_PORT_DESCR) {
+ switch (tlv_type) {
+ case LLDP_TLV_PORT_DESCR:
free(port->p_descr);
port->p_descr = b;
- } else if (tlv_type == LLDP_TLV_SYSTEM_NAME) {
+ break;
+ case LLDP_TLV_SYSTEM_NAME:
free(chassis->c_name);
chassis->c_name = b;
- } else {
+ break;
+ case LLDP_TLV_SYSTEM_DESCR:
free(chassis->c_descr);
chassis->c_descr = b;
+ break;
+ default:
+ /* unreachable */
+ free(b);
+ break;
}
break;
case LLDP_TLV_SYSTEM_CAP:
hardware->h_ifname);
break;
}
+ free(port->p_med_location[loctype - 1].data);
if ((port->p_med_location[loctype - 1].data =
(char*)malloc(tlv_size - 5)) == NULL) {
log_warn("lldp", "unable to allocate memory "
}
switch (tlv_subtype) {
case LLDP_TLV_MED_IV_HW:
+ free(chassis->c_med_hw);
chassis->c_med_hw = b;
break;
case LLDP_TLV_MED_IV_FW:
+ free(chassis->c_med_fw);
chassis->c_med_fw = b;
break;
case LLDP_TLV_MED_IV_SW:
+ free(chassis->c_med_sw);
chassis->c_med_sw = b;
break;
case LLDP_TLV_MED_IV_SN:
+ free(chassis->c_med_sn);
chassis->c_med_sn = b;
break;
case LLDP_TLV_MED_IV_MANUF:
+ free(chassis->c_med_manuf);
chassis->c_med_manuf = b;
break;
case LLDP_TLV_MED_IV_MODEL:
+ free(chassis->c_med_model);
chassis->c_med_model = b;
break;
case LLDP_TLV_MED_IV_ASSET:
+ free(chassis->c_med_asset);
chassis->c_med_asset = b;
break;
+ default:
+ /* unreachable */
+ free(b);
+ break;
}
port->p_med_cap_enabled |=
LLDP_MED_CAP_IV;