Submitted By: Douglas R. Reno Date: 2026-02-25 Initial Package Version: 3.10.2 Upstream Status: Applied Origin: Upstream (commits 2897ca48, 9cc562cc1, 79f47309, 2da6a944, and 5337e297) Description: Fixes five security vulnerabilities in the MP3 decoding logic that can allow for denial of service (application crashes) as well as information disclosure. This fixes CVE-2026-1764, CVE-2026-1765, CVE-2026-1766, and CVE-2026-1767, and includes the fix for issue #426 upstream that does not have a CVE assigned for it. diff -Naurp localsearch-3.10.2.orig/src/extractor/tracker-extract-mp3.c localsearch-3.10.2/src/extractor/tracker-extract-mp3.c --- localsearch-3.10.2.orig/src/extractor/tracker-extract-mp3.c 2025-12-10 04:41:42.000000000 -0600 +++ localsearch-3.10.2/src/extractor/tracker-extract-mp3.c 2026-02-25 12:58:30.458110764 -0600 @@ -1420,12 +1420,12 @@ static void extract_performers_tags (id3v2tag *tag, const gchar *data, guint pos, size_t csize, id3tag *info, gfloat version) { gchar text_encode; - guint offset = 0; + size_t offset = 0; GSList *performers; gint n_performers = 0; text_encode = data[pos]; - pos += 1; + offset += 1; performers = NULL; while (pos + offset < csize) { @@ -1435,9 +1435,13 @@ extract_performers_tags (id3v2tag *tag, gint text_performer_len; gchar *performer = NULL; - text_instrument = &data[pos]; - text_instrument_len = id3v2_strlen (text_encode, text_instrument, csize - 1); - offset = text_instrument_len + id3v2_nul_size (text_encode); + text_instrument = &data[pos + offset]; + text_instrument_len = id3v2_strlen (text_encode, text_instrument, csize - offset); + offset += text_instrument_len + id3v2_nul_size (text_encode); + + if (pos + offset >= csize) + break; + text_performer = &data[pos + offset]; if (version == 2.4f) { @@ -1450,7 +1454,7 @@ extract_performers_tags (id3v2tag *tag, n_performers += 1; text_performer_len = id3v2_strlen (text_encode, text_performer, csize - offset); - pos += text_instrument_len + text_performer_len + 2*id3v2_nul_size (text_encode); + offset += text_performer_len + id3v2_nul_size (text_encode); } if (performers) { @@ -1481,8 +1485,12 @@ extract_txxx_tags (id3v2tag *tag, const text_desc = &data[pos + 4]; /* $00 (00) */ text_desc_len = id3v2_strlen (text_encode, text_desc, csize - 4); - offset = 4 + text_desc_len + id3v2_nul_size (text_encode); - text = &data[pos + offset]; /* */ + offset = 4 + text_desc_len + id3v2_nul_size (text_encode); + + if (pos + offset >= csize) + return; + + text = &data[pos + offset]; /* */ if (version == 2.3f) { description = id3v2_text_to_utf8 (data[pos], &data[pos + 1], csize - 1, info); @@ -1558,6 +1566,46 @@ extract_ufid_tags (id3v2tag *tag, const } static void +extract_comm_tag (id3v2tag *tag, + const gchar *data, + guint pos, + size_t csize, + id3tag *info, + gfloat version) +{ + gchar *word = NULL; + gchar text_encode; + const gchar *text_desc; + const gchar *text; + guint offset; + gint text_desc_len; + + text_encode = data[pos + 0]; /* $xx */ + text_desc = &data[pos + 4]; /* $00 (00) */ + text_desc_len = id3v2_strlen (text_encode, text_desc, csize - 4); + + offset = 4 + text_desc_len + id3v2_nul_size (text_encode); + + if (offset >= csize) + return; + + text = &data[pos + offset]; /* */ + + if (version == 2.3f) + word = id3v2_text_to_utf8 (text_encode, text, csize - offset, info); + else + word = id3v24_text_to_utf8 (text_encode, text, csize - offset, info); + + if (!tracker_is_empty_string (word)) { + g_strstrip (word); + g_free (tag->comment); + tag->comment = word; + } else { + g_free (word); + } +} + +static void get_id3v24_tags (id3v24frame frame, const gchar *data, size_t csize, @@ -1596,35 +1644,9 @@ get_id3v24_tags (id3v24frame f break; } - case ID3V24_COMM: { - gchar *word; - gchar text_encode; - const gchar *text_desc; - const gchar *text; - guint offset; - gint text_desc_len; - - text_encode = data[pos + 0]; /* $xx */ - text_desc = &data[pos + 4]; /* $00 (00) */ - text_desc_len = id3v2_strlen (text_encode, text_desc, csize - 4); - - offset = 4 + text_desc_len + id3v2_nul_size (text_encode); - text = &data[pos + offset]; /* */ - - if (offset >= csize) - break; - - word = id3v24_text_to_utf8 (text_encode, text, csize - offset, info); - - if (!tracker_is_empty_string (word)) { - g_strstrip (word); - g_free (tag->comment); - tag->comment = word; - } else { - g_free (word); - } + case ID3V24_COMM: + extract_comm_tag (tag, data, pos, csize, info, 2.4f); break; - } case ID3V24_TMCL: { extract_performers_tags (tag, data, pos, csize, info, 2.4f); @@ -1804,33 +1826,9 @@ get_id3v23_tags (id3v24frame f break; } - case ID3V24_COMM: { - gchar *word; - gchar text_encode; - const gchar *text_desc; - const gchar *text; - guint offset; - gint text_desc_len; - - text_encode = data[pos + 0]; /* $xx */ - text_desc = &data[pos + 4]; /* $00 (00) */ - text_desc_len = id3v2_strlen (text_encode, text_desc, csize - 4); - - offset = 4 + text_desc_len + id3v2_nul_size (text_encode); - text = &data[pos + offset]; /* */ - - word = id3v2_text_to_utf8 (text_encode, text, csize - offset, info); - - if (!tracker_is_empty_string (word)) { - g_strstrip (word); - g_free (tag->comment); - tag->comment = word; - } else { - g_free (word); - } - + case ID3V24_COMM: + extract_comm_tag (tag, data, pos, csize, info, 2.4f); break; - } case ID3V24_IPLS: { extract_performers_tags (tag, data, pos, csize, info, 2.3f); @@ -2579,6 +2577,7 @@ parse_id3v20 (const gchar *data break; } else if (csize == 0) { g_debug ("[v20] Content size was 0, moving to next frame"); + continue; } /* Early versions do not have unsynch per frame */