summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Hansson <hansson@google.com>2020-06-17 16:58:24 +0100
committermosimchah <mosimchah@gmail.com>2021-02-06 22:54:03 -0500
commit6f211e847a06f69071f4abbc71faf3e470a3ada3 (patch)
tree188839ca26719ca7a8a86d6d37e8d3c7d4566de6
parent8715f623def52976cc15ca3c5a582c20591a505c (diff)
Handle 64-bit and end-of-file box lengths in IsoInterfaceq10.0
The previous code didn't recognize the special cases of - length 0 => the box extends to the end of file - length 1 => the real length is 64-bit data after the type As a result, this could in certain cases lead to video files being incorrectly parsed in location data not being redacted. Bug: 134155286 Test: atest MediaStore_Video_MediaTest Change-Id: Idad81e161bb998c933ac8a81a3ebf12f59391a16 Merged-In: Idad81e161bb998c933ac8a81a3ebf12f59391a16 (cherry picked from commit e0eec792474a1ab0cc327a3fc53440fbb3c2abf4)
-rw-r--r--src/com/android/providers/media/util/IsoInterface.java53
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]);
}
}