From 1e76eb4e71844a421aa0aef1db6c1f07368427ea Mon Sep 17 00:00:00 2001 From: Kieran Kunhya Date: Fri, 12 Jun 2026 11:16:34 +0100 Subject: [PATCH] upipe-ts: fix use-after-free parsing PMT CA descriptors uref_ts_flow_get_descriptor() returns a pointer directly into flow_def's udict inline buffer. The uref_ts_flow_set_capid()/set_sysid() calls (and the cat_onid/cat_esid sets inside upipe_ts_catd_parse_bissca_descs) add attributes to that same uref, which can realloc the udict buffer and invalidate the descriptor pointer. Subsequent reads through it (desc09_get_sysid, the loop advance, and the BISS-CA parse) were use-after-free, as caught by AddressSanitizer at desc09_get_sysid(). Parse a stack copy of the descriptor list instead, so the descriptor reads are independent of any reallocation of flow_def. This mirrors the existing VLA copy pattern in upipe_ts_pmtd_parse_descs(); len is bounded by the PMT program_info_length. Co-Authored-By: Claude Fable 5 --- lib/upipe-ts/upipe_ts_demux.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/upipe-ts/upipe_ts_demux.c b/lib/upipe-ts/upipe_ts_demux.c index cc7018caa..0ccb141d5 100644 --- a/lib/upipe-ts/upipe_ts_demux.c +++ b/lib/upipe-ts/upipe_ts_demux.c @@ -1767,11 +1767,18 @@ static int upipe_ts_demux_program_pmtd_new_flow_def( upipe_ts_demux_program_build_flow_def(upipe); - const uint8_t *desc = NULL; + const uint8_t *desc_attr = NULL; size_t len = 0; bool dvb_cissa = false; int sysid = -1; - if (ubase_check(uref_ts_flow_get_descriptor(flow_def, &desc, &len, 0))) { + if (ubase_check(uref_ts_flow_get_descriptor(flow_def, &desc_attr, &len, + 0))) { + /* desc_attr points inside flow_def's udict buffer, which the + * uref_ts_flow_set_* calls below may realloc, so parse a copy + * (len is bounded by PMT program_info_length) */ + uint8_t descl_copy[len + 1]; + memcpy(descl_copy, desc_attr, len); + const uint8_t *desc = descl_copy; while (len >= DESC_HEADER_SIZE) { uint16_t desc_len = desc_get_length(desc); if (desc_len + DESC_HEADER_SIZE > len) @@ -1782,8 +1789,9 @@ static int upipe_ts_demux_program_pmtd_new_flow_def( case 0x9: valid = desc09_validate(desc); if (valid) { - uref_ts_flow_set_capid(flow_def, desc09_get_pid(desc)); + uint16_t capid = desc09_get_pid(desc); sysid = desc09_get_sysid(desc); + uref_ts_flow_set_capid(flow_def, capid); uref_ts_flow_set_sysid(flow_def, sysid); switch (sysid) { case 0x2610: