ref: 805be6bd1e0670916a41d0cd33623608b44f78a2
parent: b9862e2e3d585d1de25143b27ca19df79e9921c5
author: Hugo Lefeuvre <hle@debian.org>
date: Sun May 5 06:37:11 EDT 2019
mp4read: moovin should not alter caller's g_atom moov blocks contain MP4 file metadata. mp4read.c parses moov blocks using moovin, which recursively calls parse to process subblocks. In order to use the parse function, moovin modifies the value of g_atom, which is a global, static variable. When moovin returns, the position of the g_atom pointer has thus changed. For example it might be pointing to the last element of a trak[], meaning that g_atom++ pushes it out-of-bounds. the result is a buffer-over-read later at line 767. fix: moovin should not modify g_atom from the point of view of its caller. Save g_atom's value at the beginning of moovin calls and reset it before returning. fixes #34.
--- a/frontend/mp4read.c
+++ b/frontend/mp4read.c
@@ -797,7 +797,8 @@
{
long apos = ftell(g_fin);
uint32_t atomsize;
- int err;
+ creator_t *old_atom = g_atom;
+ int err, ret = sizemax;
static creator_t mvhd[] = {
{ATOM_NAME, "mvhd"},
@@ -841,8 +842,11 @@
g_atom = mvhd;
atomsize = sizemax + apos - ftell(g_fin);
- if (parse(&atomsize) < 0)
+ if (parse(&atomsize) < 0) {
+ g_atom = old_atom;
return ERR_FAIL;
+ }
+
fseek(g_fin, apos, SEEK_SET);
while (1)
@@ -856,13 +860,16 @@
err = parse(&atomsize);
//fprintf(stderr, "SIZE: %x/%x\n", atomsize, sizemax);
if (err >= 0)
- return sizemax;
- if (err != ERR_UNSUPPORTED)
- return err;
+ break;
+ if (err != ERR_UNSUPPORTED) {
+ ret = err;
+ break;
+ }
//fprintf(stderr, "UNSUPP\n");
}
- return sizemax;
+ g_atom = old_atom;
+ return ret;
}