summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Soffke <christian.soffke@gmail.com>2024-11-23 14:59:03 +0100
committerChristian Soffke <christian.soffke@gmail.com>2024-11-30 15:45:40 +0100
commit0469a95bee248339e2eb5770b3161500f2712491 (patch)
treecb3683be381f37cf1674ae966053d1844a2cd28b
parentc6fb789b3baddd0ea550c3aeac5bd3e2574d8002 (diff)
downloadrockbox-0469a95bee.tar.gz
rockbox-0469a95bee.zip
Playlist Viewer: Mitigate FS#13518 (stack overflow)
Playlist Viewer hangs indefinitely on tracks with long Comment fields Commit 2156d98 (metadata: mp3: Improve support for long tags) has allowed the length of parsed tags to exceed ID3V2_MAX_ITEM_SIZE. Overly long tags may blow the stack due to a stack-allocated buffer in the metadata parsing routine, that can reach 3 times the size of the id3v2 and id3v1 buffers combined. This patch moves the mp3entry struct used by the Playlist Viewer off the stack and onto the plugin buffer instead, which helps prevent a stack overflow in cases such as the example posted in FS#13518. Future patches to either constrain ID3V2_BUF_SIZE to ~1120 bytes or to lower the stack usage of metadata parsing will still be required to fully address the issue. Change-Id: I2f436195bc8df4d785b1880f6ab167783a162020
-rw-r--r--apps/playlist_viewer.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/apps/playlist_viewer.c b/apps/playlist_viewer.c
index c3c6f6fa29..2b457ba1c9 100644
--- a/apps/playlist_viewer.c
+++ b/apps/playlist_viewer.c
@@ -115,6 +115,7 @@ struct playlist_viewer {
int moving_playlist_index; /* Playlist-relative index (as opposed to
viewer-relative index) of moving track */
struct playlist_buffer buffer;
+ struct mp3entry *id3;
};
struct playlist_search_data
@@ -385,10 +386,16 @@ static bool playlist_viewer_init(struct playlist_viewer * viewer,
return false;
}
+ size_t id3_size = sizeof(*viewer->id3);
+
buffer = plugin_get_buffer(&buffer_size);
- if (!buffer || buffer_size <= MAX_PATH)
+ if (!buffer || buffer_size <= MAX_PATH + id3_size)
return false;
+ viewer->id3 = (void *) buffer;
+ buffer += id3_size;
+ buffer_size -= id3_size;
+
if (!filename)
{
viewer->playlist = NULL;
@@ -491,16 +498,15 @@ static void format_line(struct playlist_entry* track, char* str,
))
{
track->attr |= PLAYLIST_ATTR_RETRIEVE_ID3_ATTEMPTED;
- struct mp3entry id3;
bool retrieve_success = retrieve_id3_tags(track->index, track->name,
- &id3, METADATA_EXCLUDE_ID3_PATH);
+ viewer.id3, METADATA_EXCLUDE_ID3_PATH);
if (retrieve_success)
{
if (!id3viewc)
{
id3viewc = track->name + strlen(track->name) + 1;
}
- struct mp3entry * pid3 = &id3;
+ struct mp3entry * pid3 = viewer.id3;
id3viewc[0] = '\0';
if (global_settings.playlist_viewer_track_display ==
PLAYLIST_VIEWER_ENTRY_SHOW_ID3_TITLE_AND_ALBUM)
@@ -573,11 +579,12 @@ static void format_line(struct playlist_entry* track, char* str,
static enum pv_onplay_result show_track_info(const struct playlist_entry *current_track)
{
- struct mp3entry id3;
- bool id3_retrieval_successful = retrieve_id3_tags(current_track->index, current_track->name, &id3, 0);
+ bool id3_retrieval_successful = retrieve_id3_tags(current_track->index,
+ current_track->name,
+ viewer.id3, 0);
return id3_retrieval_successful &&
- browse_id3_ex(&id3, viewer.playlist, current_track->display_index,
+ browse_id3_ex(viewer.id3, viewer.playlist, current_track->display_index,
viewer.num_tracks, NULL, 1) ? PV_ONPLAY_USB : PV_ONPLAY_UNCHANGED;
}