libudfread | branch: master | Petri Hintukainen <[email protected]> | 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; _______________________________________________ libbluray-devel mailing list [email protected] https://mailman.videolan.org/listinfo/libbluray-devel
