[libbluray-devel] Fix possible OOB read in decode_file_identifier() (corrupt input)

Petri Hintukainen git at videolan.org
Sun Jun 11 16:42:40 CEST 2017


libudfread | branch: master | Petri Hintukainen <phintuka at gmail.com> | Sun Jun 11 17:27:23 2017 +0300| [9a7128a28e1f699b0e2d1e0be01bc12846d93b0f] | committer: Petri Hintukainen

Fix possible OOB read in decode_file_identifier() (corrupt input)

> http://git.videolan.org/gitweb.cgi/libudfread.git/?a=commit;h=9a7128a28e1f699b0e2d1e0be01bc12846d93b0f
---

 src/ecma167.c | 12 +++++++++++-
 src/ecma167.h |  2 +-
 src/udfread.c |  8 +++++++-
 3 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/src/ecma167.c b/src/ecma167.c
index 142596f..9d16082 100644
--- a/src/ecma167.c
+++ b/src/ecma167.c
@@ -158,16 +158,26 @@ void decode_file_set_descriptor(const uint8_t *p, struct file_set_descriptor *fs
 }
 
 /* File Identifier (ECMA 167 4/14.4) */
-size_t decode_file_identifier(const uint8_t *p, struct file_identifier *fi)
+size_t decode_file_identifier(const uint8_t *p, size_t size, struct file_identifier *fi)
 {
     size_t l_iu; /* length of implementation use field */
 
+    if (size < 38) {
+        ecma_error("not enough data\n");
+        return 0;
+    }
+
     fi->characteristic = _get_u8(p + 18);
     fi->filename_len   = _get_u8(p + 19);
     decode_long_ad(p + 20, &fi->icb);
 
     l_iu = _get_u16(p + 36);
 
+    if (size < 38 + l_iu + fi->filename_len) {
+        ecma_error("not enough data\n");
+        return 0;
+    }
+
     if (fi->filename_len) {
         memcpy(fi->filename, p + 38 + l_iu, fi->filename_len);
     }
diff --git a/src/ecma167.h b/src/ecma167.h
index 227a3a1..a38e97e 100644
--- a/src/ecma167.h
+++ b/src/ecma167.h
@@ -193,7 +193,7 @@ struct file_identifier {
     uint8_t        filename[256];
 };
 
-size_t decode_file_identifier(const uint8_t *p, struct file_identifier *fi);
+size_t decode_file_identifier(const uint8_t *p, size_t size, struct file_identifier *fi);
 
 /* File Entry (ECMA 167, 4/14.9) */
 /* Extended File Entry (ECMA 167, 4/14.17) */
diff --git a/src/udfread.c b/src/udfread.c
index 1f9b4a4..5d3bedf 100644
--- a/src/udfread.c
+++ b/src/udfread.c
@@ -891,6 +891,7 @@ static int _parse_dir(const uint8_t *data, uint32_t length, struct udf_dir *dir)
     int            tag_id;
 
     while (p < end) {
+        size_t used;
 
         tag_id = decode_descriptor_tag(p);
         if (tag_id != ECMA_FileIdentifierDescriptor) {
@@ -903,7 +904,12 @@ static int _parse_dir(const uint8_t *data, uint32_t length, struct udf_dir *dir)
             return -1;
         }
 
-        p += decode_file_identifier(p, &fid);
+        used = decode_file_identifier(p, end - p, &fid);
+        if (used == 0) {
+            /* not enough data. keep the entries we already have. */
+            break;
+        }
+        p += used;
 
         if (fid.characteristic & CHAR_FLAG_PARENT) {
             continue;



More information about the libbluray-devel mailing list