Refuse to read CE data blocks from after the end of ISO filesystem

This commit is contained in:
Thomas Schmitt 2017-08-19 16:55:08 +02:00
parent 31088d9acc
commit 2a64d89e6e
5 changed files with 16 additions and 7 deletions

View File

@ -1577,8 +1577,8 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
SuspIterator *iter;
iter = susp_iter_new(fsdata->src, record, fsdata->len_skp,
fsdata->msgid);
iter = susp_iter_new(fsdata->src, record, fsdata->nblocks,
fsdata->len_skp, fsdata->msgid);
if (iter == NULL) {
{ret = ISO_OUT_OF_MEM; goto ex;}
}
@ -2404,7 +2404,8 @@ int read_root_susp_entries(_ImageFsData *data, uint32_t block)
* In that case, we need to set info->len_skp to 15!!
*/
iter = susp_iter_new(data->src, record, data->len_skp, data->msgid);
iter = susp_iter_new(data->src, record, data->nblocks, data->len_skp,
data->msgid);
if (iter == NULL) {
ret = ISO_OUT_OF_MEM; goto ex;
}

View File

@ -8883,7 +8883,8 @@ int iso_conv_name_chars(IsoWriteOpts *opts, char *name, size_t name_len,
/** Unable to obtain root directory (FATAL,HIGH, -418) */
#define ISO_NO_ROOT_DIR 0xF030FE5E
/** Zero sized or oversized SUSP CE area found (FAILURE, HIGH, -419) */
/** Zero sized, oversized, or mislocated SUSP CE area found
(FAILURE, HIGH, -419) */
#define ISO_SUSP_WRONG_CE_SIZE 0xE830FE5D

View File

@ -550,7 +550,7 @@ const char *iso_error_to_msg(int errcode)
case ISO_NO_ROOT_DIR:
return "Unable to obtain root directory";
case ISO_SUSP_WRONG_CE_SIZE:
return "Zero sized or oversized SUSP CE area found";
return "Zero sized, oversized, or mislocated SUSP CE area found";
default:
return "Unknown error";
}

View File

@ -254,7 +254,7 @@ typedef struct susp_iterator SuspIterator;
SuspIterator *
susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record,
uint8_t len_skp, int msgid);
uint32_t fs_blocks, uint8_t len_skp, int msgid);
/**
* Get the next SUSP System User Entry using given iterator.

View File

@ -35,6 +35,9 @@ struct susp_iterator
IsoDataSource *src;
int msgid;
/* Number of blocks in the ISO 9660 filesystem */
uint32_t fs_blocks;
/* block and offset for next continuation area */
uint32_t ce_block;
uint32_t ce_off;
@ -47,7 +50,7 @@ struct susp_iterator
SuspIterator*
susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record,
uint8_t len_skp, int msgid)
uint32_t fs_blocks, uint8_t len_skp, int msgid)
{
int pad = (record->len_fi[0] + 1) % 2;
struct susp_iterator *iter = malloc(sizeof(struct susp_iterator));
@ -60,6 +63,7 @@ susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record,
iter->size = record->len_dr[0] - record->len_fi[0] - 33 - pad;
iter->src = src;
iter->msgid = msgid;
iter->fs_blocks = fs_blocks;
iter->ce_len = 0;
iter->buffer = NULL;
@ -108,6 +112,9 @@ int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue,
BLOCK_SIZE);
if (nblocks <= 0 || iter->ce_len > ISO_SUSP_MAX_CE_BYTES)
return ISO_SUSP_WRONG_CE_SIZE;
if (((uint64_t) iter->ce_block) + skipped_blocks + nblocks >
(uint64_t) iter->fs_blocks)
return ISO_SUSP_WRONG_CE_SIZE;
iter->buffer = realloc(iter->buffer, nblocks * BLOCK_SIZE);
/* Read blocks needed to cache the given CE area range */