From d7ca37a89ad9a7daf251a34cc693f834a795fbb5 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 15 Nov 2023 16:56:48 -0500 Subject: [PATCH] MT#55283 check DTLS src/dst addressses Check addresses of received DTLS packets against known ICE pairs if ICE is in use. Ignore packets that don't correspond to known ICE pairs. Credit to the the team at EnableSecurity.com for disclosure. Ref: https://github.com/EnableSecurity/advisories/tree/master/ES2023-03-rtpengine-dtls-hello-race Change-Id: I45197c50aedeb078763f2f444225ddbda78d9349 (cherry picked from commit e969a79428ac4a15cdf1c0a1c6f266dbdc7e60b6) --- daemon/ice.c | 21 +++++++++++++++++++++ daemon/media_socket.c | 13 +++++++++++++ include/ice.h | 3 +++ 3 files changed, 37 insertions(+) diff --git a/daemon/ice.c b/daemon/ice.c index eb3666196..9afc8d4ea 100644 --- a/daemon/ice.c +++ b/daemon/ice.c @@ -1396,3 +1396,24 @@ void ice_remote_candidates(GQueue *out, struct ice_agent *ag) { g_queue_clear(&all_compos); } + +bool ice_peer_address_known(struct ice_agent *ag, const endpoint_t *sin, struct packet_stream *ps, + const struct local_intf *ifa) +{ + mutex_lock(&ag->lock); + bool ret = false; + + struct ice_candidate *cand = __cand_lookup(ag, sin, ps->component); + if (!cand) + goto out; + struct ice_candidate_pair *pair = __pair_lookup(ag, cand, ifa); + if (!pair) + goto out; + if (!PAIR_ISSET(pair, VALID)) + goto out; + + ret = true; +out: + mutex_unlock(&ag->lock); + return ret; +} diff --git a/daemon/media_socket.c b/daemon/media_socket.c index dabdecea4..54d3a0ec4 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -1540,6 +1540,19 @@ static void __stream_ssrc(struct packet_stream *in_srtp, struct packet_stream *o // 1 = same as 0, but stream can be kernelized static int media_demux_protocols(struct packet_handler_ctx *phc) { if (MEDIA_ISSET(phc->mp.media, DTLS) && is_dtls(&phc->s)) { + // verify DTLS packet against ICE checks if present + if (MEDIA_ISSET(phc->mp.media, ICE) && phc->mp.media->ice_agent) { + if (!ice_peer_address_known(phc->mp.media->ice_agent, &phc->mp.fsin, phc->mp.stream, + phc->mp.sfd->local_intf)) + { + ilog(LOG_DEBUG, "Ignoring DTLS packet from %s%s%s to %s as no matching valid " + "ICE candidate pair exists", + FMT_M(endpoint_print_buf(&phc->mp.fsin)), + endpoint_print_buf(&phc->mp.sfd->socket.local)); + return 0; + } + } + mutex_lock(&phc->mp.stream->in_lock); int ret = dtls(phc->mp.sfd, &phc->s, &phc->mp.fsin); mutex_unlock(&phc->mp.stream->in_lock); diff --git a/include/ice.h b/include/ice.h index b9980bbbe..781265563 100644 --- a/include/ice.h +++ b/include/ice.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "str.h" #include "obj.h" #include "aux.h" @@ -150,6 +151,8 @@ void ice_free(void); enum ice_candidate_type ice_candidate_type(const str *s); int ice_has_related(enum ice_candidate_type); void ice_foundation(str *); +bool ice_peer_address_known(struct ice_agent *, const endpoint_t *, struct packet_stream *, + const struct local_intf *ifa); void ice_agent_init(struct ice_agent **agp, struct call_media *media); void ice_update(struct ice_agent *, struct stream_params *);