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; SuspIterator *iter;
iter = susp_iter_new(fsdata->src, record, fsdata->len_skp, iter = susp_iter_new(fsdata->src, record, fsdata->nblocks,
fsdata->msgid); fsdata->len_skp, fsdata->msgid);
if (iter == NULL) { if (iter == NULL) {
{ret = ISO_OUT_OF_MEM; goto ex;} {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!! * 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) { if (iter == NULL) {
ret = ISO_OUT_OF_MEM; goto ex; 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) */ /** Unable to obtain root directory (FATAL,HIGH, -418) */
#define ISO_NO_ROOT_DIR 0xF030FE5E #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 #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: case ISO_NO_ROOT_DIR:
return "Unable to obtain root directory"; return "Unable to obtain root directory";
case ISO_SUSP_WRONG_CE_SIZE: 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: default:
return "Unknown error"; return "Unknown error";
} }

View File

@ -254,7 +254,7 @@ typedef struct susp_iterator SuspIterator;
SuspIterator * SuspIterator *
susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record, 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. * Get the next SUSP System User Entry using given iterator.

View File

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