diff options
author | Anton Hansson <hansson@google.com> | 2020-12-03 10:24:36 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-12-03 10:24:36 +0000 |
commit | 7f98f6c6959c07c9898a2e4f2119b9c3fc930a84 (patch) | |
tree | 1e774347442ad4173b2da51d0c329f376ea96bbd | |
parent | 3c17c4b79ced51eefb4ae14a9b76c85887c1902d (diff) | |
parent | e0eec792474a1ab0cc327a3fc53440fbb3c2abf4 (diff) |
Handle 64-bit and end-of-file box lengths in IsoInterface am: e0eec79247
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/providers/MediaProvider/+/13143318
Change-Id: Ia5ba27b95dc9a3cd9b3904b2b5b783bc651c78bc
-rw-r--r-- | src/com/android/providers/media/util/IsoInterface.java | 53 |
1 files changed, 40 insertions, 13 deletions
diff --git a/src/com/android/providers/media/util/IsoInterface.java b/src/com/android/providers/media/util/IsoInterface.java index 6843021b..35825acd 100644 --- a/src/com/android/providers/media/util/IsoInterface.java +++ b/src/com/android/providers/media/util/IsoInterface.java @@ -100,6 +100,7 @@ public class IsoInterface { public UUID uuid; public byte[] data; public List<Box> children; + public int headerSize; public Box(int type, long[] range) { this.type = type; @@ -133,46 +134,72 @@ public class IsoInterface { private static @Nullable Box parseNextBox(@NonNull FileDescriptor fd, long end, @NonNull String prefix) throws ErrnoException, IOException { final long pos = Os.lseek(fd, 0, OsConstants.SEEK_CUR); - if (pos == end) { + + int headerSize = 8; + if (end - pos < headerSize) { return null; } - final long len = Integer.toUnsignedLong(readInt(fd)); - if (len <= 0 || pos + len > end) { + long len = Integer.toUnsignedLong(readInt(fd)); + final int type = readInt(fd); + + if (len == 0) { + // Length 0 means the box extends to the end of the file. + len = end - pos; + } else if (len == 1) { + // Actually 64-bit box length. + headerSize += 8; + long high = readInt(fd); + long low = readInt(fd); + len = (high << 32L) | (low & 0xffffffffL); + } + + if (len < headerSize || pos + len > end) { Log.w(TAG, "Invalid box at " + pos + " of length " + len - + " reached beyond end of parent " + end); + + ". End of parent " + end); return null; } // Skip past legacy data on 'meta' box - final int type = readInt(fd); if (type == BOX_META) { readInt(fd); } final Box box = new Box(type, new long[] { pos, len }); - if (LOGV) { - Log.v(TAG, prefix + "Found box " + typeToString(type) - + " at " + pos + " length " + len); - } + box.headerSize = headerSize; // Parse UUID box if (type == BOX_UUID) { + box.headerSize += 16; box.uuid = readUuid(fd); if (LOGV) { Log.v(TAG, prefix + " UUID " + box.uuid); } - box.data = new byte[(int) (len - 8 - 16)]; + if (len > Integer.MAX_VALUE) { + Log.w(TAG, "Skipping abnormally large uuid box"); + return null; + } + + box.data = new byte[(int) (len - box.headerSize)]; IoBridge.read(fd, box.data, 0, box.data.length); } // Parse XMP box if (type == BOX_XMP) { - box.data = new byte[(int) (len - 8)]; + if (len > Integer.MAX_VALUE) { + Log.w(TAG, "Skipping abnormally large xmp box"); + return null; + } + box.data = new byte[(int) (len - box.headerSize)]; IoBridge.read(fd, box.data, 0, box.data.length); } + if (LOGV) { + Log.v(TAG, prefix + "Found box " + typeToString(type) + + " at " + pos + " hdr " + box.headerSize + " length " + len); + } + // Recursively parse any children boxes if (isBoxParent(type)) { box.children = new ArrayList<>(); @@ -241,7 +268,7 @@ public class IsoInterface { LongArray res = new LongArray(); for (Box box : mFlattened) { if (box.type == type) { - res.add(box.range[0] + 8); + res.add(box.range[0] + box.headerSize); res.add(box.range[0] + box.range[1]); } } @@ -252,7 +279,7 @@ public class IsoInterface { LongArray res = new LongArray(); for (Box box : mFlattened) { if (box.type == BOX_UUID && Objects.equals(box.uuid, uuid)) { - res.add(box.range[0] + 8 + 16); + res.add(box.range[0] + box.headerSize); res.add(box.range[0] + box.range[1]); } } |