Commit 9a7128a2 authored by Petri Hintukainen's avatar Petri Hintukainen

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

parent 41da1bba
...@@ -158,16 +158,26 @@ void decode_file_set_descriptor(const uint8_t *p, struct file_set_descriptor *fs ...@@ -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) */ /* 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 */ 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->characteristic = _get_u8(p + 18);
fi->filename_len = _get_u8(p + 19); fi->filename_len = _get_u8(p + 19);
decode_long_ad(p + 20, &fi->icb); decode_long_ad(p + 20, &fi->icb);
l_iu = _get_u16(p + 36); 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) { if (fi->filename_len) {
memcpy(fi->filename, p + 38 + l_iu, fi->filename_len); memcpy(fi->filename, p + 38 + l_iu, fi->filename_len);
} }
......
...@@ -193,7 +193,7 @@ struct file_identifier { ...@@ -193,7 +193,7 @@ struct file_identifier {
uint8_t filename[256]; 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) */ /* File Entry (ECMA 167, 4/14.9) */
/* Extended File Entry (ECMA 167, 4/14.17) */ /* Extended File Entry (ECMA 167, 4/14.17) */
......
...@@ -891,6 +891,7 @@ static int _parse_dir(const uint8_t *data, uint32_t length, struct udf_dir *dir) ...@@ -891,6 +891,7 @@ static int _parse_dir(const uint8_t *data, uint32_t length, struct udf_dir *dir)
int tag_id; int tag_id;
while (p < end) { while (p < end) {
size_t used;
tag_id = decode_descriptor_tag(p); tag_id = decode_descriptor_tag(p);
if (tag_id != ECMA_FileIdentifierDescriptor) { if (tag_id != ECMA_FileIdentifierDescriptor) {
...@@ -903,7 +904,12 @@ static int _parse_dir(const uint8_t *data, uint32_t length, struct udf_dir *dir) ...@@ -903,7 +904,12 @@ static int _parse_dir(const uint8_t *data, uint32_t length, struct udf_dir *dir)
return -1; 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) { if (fid.characteristic & CHAR_FLAG_PARENT) {
continue; continue;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment