summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ldpd/labelmapping.c
diff options
context:
space:
mode:
authorrenato <renato@openbsd.org>2016-07-16 19:20:16 +0000
committerrenato <renato@openbsd.org>2016-07-16 19:20:16 +0000
commita78ea73f827928c1e19cfa5f76567b253c6e1213 (patch)
treef9bae4266a6ef06e06fb3bf69fde2a5db58ba61f /usr.sbin/ldpd/labelmapping.c
parentFix sockopt name: ICMPV6_FILTER -> ICMP6_FILTER (diff)
downloadwireguard-openbsd-a78ea73f827928c1e19cfa5f76567b253c6e1213.tar.xz
wireguard-openbsd-a78ea73f827928c1e19cfa5f76567b253c6e1213.zip
Fix parsing of mal-formed optional TLVs/Sub-TLVs.
We must detect if a TLV's length extends beyond the end of the containing message. And, if so, send a fatal "Bad TLV Length" notification message. Found with the Mu Dynamics Mu-8000 protocol fuzzer.
Diffstat (limited to 'usr.sbin/ldpd/labelmapping.c')
-rw-r--r--usr.sbin/ldpd/labelmapping.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/usr.sbin/ldpd/labelmapping.c b/usr.sbin/ldpd/labelmapping.c
index a1ec305f0ca..f8261e6d6d8 100644
--- a/usr.sbin/ldpd/labelmapping.c
+++ b/usr.sbin/ldpd/labelmapping.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: labelmapping.c,v 1.57 2016/07/15 17:09:25 renato Exp $ */
+/* $OpenBSD: labelmapping.c,v 1.58 2016/07/16 19:20:16 renato Exp $ */
/*
* Copyright (c) 2014, 2015 Renato Westphal <renato@openbsd.org>
@@ -246,9 +246,13 @@ recv_labelmessage(struct nbr *nbr, char *buf, uint16_t len, uint16_t type)
}
memcpy(&tlv, buf, TLV_HDR_SIZE);
+ tlv_len = ntohs(tlv.length);
+ if (tlv_len + TLV_HDR_SIZE > len) {
+ session_shutdown(nbr, S_BAD_TLV_LEN, msg.id, msg.type);
+ goto err;
+ }
buf += TLV_HDR_SIZE;
len -= TLV_HDR_SIZE;
- tlv_len = ntohs(tlv.length);
switch (ntohs(tlv.type)) {
case TLV_TYPE_LABELREQUEST:
@@ -334,10 +338,9 @@ recv_labelmessage(struct nbr *nbr, char *buf, uint16_t len, uint16_t type)
}
break;
default:
- if (!(ntohs(tlv.type) & UNKNOWN_FLAG)) {
+ if (!(ntohs(tlv.type) & UNKNOWN_FLAG))
send_notification_nbr(nbr, S_UNKNOWN_TLV,
msg.id, msg.type);
- }
/* ignore unknown tlv */
break;
}
@@ -708,6 +711,12 @@ tlv_decode_fec_elm(struct nbr *nbr, struct ldp_msg *msg, char *buf,
}
memcpy(&stlv, buf + off, sizeof(stlv));
+ if (stlv.length > pw_len) {
+ session_shutdown(nbr, S_BAD_TLV_LEN, msg->id,
+ msg->type);
+ return (-1);
+ }
+
switch (stlv.type) {
case SUBTLV_IFMTU:
if (stlv.length != FEC_SUBTLV_IFMTU_SIZE) {