[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