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 e969a79428)
mr10.5.7
Richard Fuchs 2 years ago
parent 398fff851e
commit 7e11cb7ae8

@ -1396,3 +1396,20 @@ 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)
{
LOCK(&ag->lock);
struct ice_candidate *cand = __cand_lookup(ag, sin, ps->component);
if (!cand)
return false;
struct ice_candidate_pair *pair = __pair_lookup(ag, cand, ifa);
if (!pair)
return false;
if (!PAIR_ISSET(pair, VALID))
return false;
return true;
}

@ -1759,6 +1759,19 @@ static bool __stream_ssrc_out(struct packet_stream *out_srtp, uint32_t ssrc_bs,
// 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);

@ -152,6 +152,8 @@ void ice_free(void);
enum ice_candidate_type ice_candidate_type(const str *s);
bool 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 *, bool allow_restart);

Loading…
Cancel
Save