if (head) {
memcpy(tlv, head, sizeof(*tlv));
head->next = NULL;
+ if (head->type == PW_TYPE_TLV) head->vp_tlv = NULL;
pairfree(&head);
}
return 0;
make_tlv:
- tlv->vp_tlv = malloc(data_len);
- if (!tlv->vp_tlv) {
- fr_strerror_printf("No memory");
- return -1;
- }
- memcpy(tlv->vp_tlv, data, data_len);
+ if (data_len > sizeof(tlv->vp_octets)) data_len = sizeof(tlv->vp_octets);
+ memcpy(tlv->vp_octets, data, data_len);
tlv->length = data_len;
+ tlv->type = PW_TYPE_OCTETS;
return 0;
}
uint8_t *ptr, *tlv, *tlv_data;
for (ptr = data + length;
- ptr != (data + packet_length);
+ ptr < (data + packet_length);
ptr += ptr[1]) {
+ if ((ptr + 2) > (data + length)) return NULL;
+
if ((ptr[0] != PW_VENDOR_SPECIFIC) ||
(ptr[1] < (2 + 4 + 3)) || /* WiMAX VSA with continuation */
(ptr[2] != 0) || (ptr[3] != 0)) { /* our requirement */
* If the vendor-length is too small, it's badly
* formed, so we stop.
*/
- if ((ptr[2 + 4 + 1]) < 3) break;
+ if ((ptr[2 + 4 + 1]) < 3) return NULL;
+
+ /*
+ * If it overflows the packet, it's bad.
+ */
+ if ((ptr + ptr[2 + 4 + 1]) > (data + packet_length)) {
+ return NULL;
+ }
tlv_length += ptr[2 + 4 + 1] - 3;
if ((ptr[2 + 4 + 1 + 1] & 0x80) == 0) break;
* our newly created memory.
*/
for (ptr = data + length;
- ptr != (data + packet_length);
+ ptr < (data + packet_length);
ptr += ptr[1]) {
int this_length;