summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJob Snijders <job@fastly.com>2021-12-18 16:35:28 +0100
committerOndrej Zajicek (work) <santiago@crfreenet.org>2021-12-18 16:35:28 +0100
commitb9f38727a7ba7c9c7e383ade80dbf77086dfce05 (patch)
treec2017a6866e927561fec65b1bfb6c6f646d5f9ca
parent00410fd6c17697a5919cb32a44f7117dd3a0834a (diff)
RPKI: Add contextual out-of-bound checks in RTR Prefix PDU handler
RFC 6810 and RFC 8210 specify that the "Max Length" value MUST NOT be less than the Prefix Length element (underflow). On the other side, overflow of the Max Length element also is possible, it being an 8-bit unsigned integer allows for values larger than 32 or 128. This also implicitly ensures there is no overflow of "Length" value. When a PDU is received where the Max Length field is corrputed, the RTR client (BIRD) should immediately terminate the session, flush all data learned from that cache, and log an error for the operator. Minor changes done by commiter.
-rw-r--r--proto/rpki/packets.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/proto/rpki/packets.c b/proto/rpki/packets.c
index dd11f997..d246dd50 100644
--- a/proto/rpki/packets.c
+++ b/proto/rpki/packets.c
@@ -737,6 +737,33 @@ rpki_handle_prefix_pdu(struct rpki_cache *cache, const struct pdu_header *pdu)
net_addr_union addr = {};
rpki_prefix_pdu_2_net_addr(pdu, &addr);
+ if (type == IPV4_PREFIX)
+ {
+ if ((addr.roa4.pxlen > addr.roa4.max_pxlen) ||
+ (addr.roa4.max_pxlen > IP4_MAX_PREFIX_LENGTH))
+ {
+ RPKI_WARN(cache->p, "Received corrupt packet from RPKI cache server: invalid pxlen or max_pxlen");
+ byte tmp[pdu->len];
+ const struct pdu_header *hton_pdu = rpki_pdu_back_to_network_byte_order((void *) tmp, (const void *) pdu);
+ rpki_send_error_pdu(cache, CORRUPT_DATA, pdu->len, hton_pdu, "Corrupted PDU: invalid pxlen or max_pxlen");
+ rpki_cache_change_state(cache, RPKI_CS_ERROR_FATAL);
+ return RPKI_ERROR;
+ }
+ }
+ else
+ {
+ if ((addr.roa6.pxlen > addr.roa6.max_pxlen) ||
+ (addr.roa6.max_pxlen > IP6_MAX_PREFIX_LENGTH))
+ {
+ RPKI_WARN(cache->p, "Received corrupt packet from RPKI cache server: invalid pxlen or max_pxlen");
+ byte tmp[pdu->len];
+ const struct pdu_header *hton_pdu = rpki_pdu_back_to_network_byte_order((void *) tmp, (const void *) pdu);
+ rpki_send_error_pdu(cache, CORRUPT_DATA, pdu->len, hton_pdu, "Corrupted PDU: invalid pxlen or max_pxlen");
+ rpki_cache_change_state(cache, RPKI_CS_ERROR_FATAL);
+ return RPKI_ERROR;
+ }
+ }
+
if (cf->ignore_max_length)
{
if (type == IPV4_PREFIX)