diff --git a/ext/fileinfo/libmagic/cdf.c b/ext/fileinfo/libmagic/cdf.c index 1034937..59af8da 100644 --- a/ext/fileinfo/libmagic/cdf.c +++ b/ext/fileinfo/libmagic/cdf.c @@ -238,14 +238,17 @@ cdf_unpack_dir(cdf_directory_t *d, char *buf) } static int -cdf_check_stream_offset(const cdf_stream_t *sst, const void *p, size_t tail) +cdf_check_stream_offset(const cdf_stream_t *sst, const cdf_header_t *h, + const void *p, size_t tail) { const char *b = (const char *)sst->sst_tab; const char *e = ((const char *)p) + tail; - if (e >= b && (size_t)(e - b) < sst->sst_dirlen * sst->sst_len) + size_t ss = sst->sst_dirlen < h->h_min_size_standard_stream ? + CDF_SHORT_SEC_SIZE(h) : CDF_SEC_SIZE(h); + if (e >= b && (size_t)(e - b) <= ss * sst->sst_len) return 0; DPRINTF((stderr, "offset begin %p end %p %zu >= %zu\n", b, e, - (size_t)(e - b), sst->sst_dirlen * sst->sst_len)); + (size_t)(e - b), ss * sst->sst_len)); errno = EFTYPE; return -1; } @@ -695,7 +698,7 @@ cdf_read_summary_info(const cdf_info_t *info, const cdf_header_t *h, } int -cdf_read_property_info(const cdf_stream_t *sst, uint32_t offs, +cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h, uint32_t offs, cdf_property_info_t **info, size_t *count, size_t *maxcount) { const cdf_section_header_t *shp; @@ -715,7 +718,7 @@ cdf_read_property_info(const cdf_stream_t *sst, uint32_t offs, goto out; } shp = (const void *)((const char *)sst->sst_tab + offs); - if (cdf_check_stream_offset(sst, shp, sizeof(*shp)) == -1) + if (cdf_check_stream_offset(sst, h, shp, sizeof(*shp)) == -1) goto out; sh.sh_len = CDF_TOLE4(shp->sh_len); #define CDF_SHLEN_LIMIT (UINT32_MAX / 8) @@ -745,7 +748,7 @@ cdf_read_property_info(const cdf_stream_t *sst, uint32_t offs, *count += sh.sh_properties; p = (const void *)((const char *)sst->sst_tab + offs + sizeof(sh)); e = (const void *)(((const char *)shp) + sh.sh_len); - if (cdf_check_stream_offset(sst, e, 0) == -1) + if (cdf_check_stream_offset(sst, h, e, 0) == -1) goto out; for (i = 0; i < sh.sh_properties; i++) { q = (const uint32_t *)((const char *)p + @@ -856,7 +859,7 @@ out: } int -cdf_unpack_summary_info(const cdf_stream_t *sst, cdf_summary_info_header_t *ssi, +cdf_unpack_summary_info(const cdf_stream_t *sst, const cdf_header_t *h, cdf_summary_info_header_t *ssi, cdf_property_info_t **info, size_t *count) { size_t maxcount; @@ -864,8 +867,8 @@ cdf_unpack_summary_info(const cdf_stream_t *sst, cdf_summary_info_header_t *ssi, const cdf_section_declaration_t *sd = (const void *) ((const char *)sst->sst_tab + CDF_SECTION_DECLARATION_OFFSET); - if (cdf_check_stream_offset(sst, si, sizeof(*si)) == -1 || - cdf_check_stream_offset(sst, sd, sizeof(*sd)) == -1) + if (cdf_check_stream_offset(sst, h, si, sizeof(*si)) == -1 || + cdf_check_stream_offset(sst, h, sd, sizeof(*sd)) == -1) return -1; ssi->si_byte_order = CDF_TOLE2(si->si_byte_order); ssi->si_os_version = CDF_TOLE2(si->si_os_version); @@ -876,7 +879,7 @@ cdf_unpack_summary_info(const cdf_stream_t *sst, cdf_summary_info_header_t *ssi, *count = 0; maxcount = 0; *info = NULL; - if (cdf_read_property_info(sst, CDF_TOLE4(sd->sd_offset), + if (cdf_read_property_info(sst, h, CDF_TOLE4(sd->sd_offset), info, count, &maxcount) == -1) return -1; return 0; @@ -1163,7 +1166,7 @@ cdf_dump_summary_info(const cdf_header_t *h, const cdf_stream_t *sst) size_t count; (void)&h; - if (cdf_unpack_summary_info(sst, &ssi, &info, &count) == -1) + if (cdf_unpack_summary_info(sst, h, &ssi, &info, &count) == -1) return; (void)fprintf(stderr, "Endian: %x\n", ssi.si_byte_order); (void)fprintf(stderr, "Os Version %d.%d\n", ssi.si_os_version & 0xff, diff --git a/ext/fileinfo/libmagic/cdf.h b/ext/fileinfo/libmagic/cdf.h index c056a82..c27d1ea 100644 --- a/ext/fileinfo/libmagic/cdf.h +++ b/ext/fileinfo/libmagic/cdf.h @@ -280,12 +280,12 @@ int cdf_read_ssat(const cdf_info_t *, const cdf_header_t *, const cdf_sat_t *, cdf_sat_t *); int cdf_read_short_stream(const cdf_info_t *, const cdf_header_t *, const cdf_sat_t *, const cdf_dir_t *, cdf_stream_t *); -int cdf_read_property_info(const cdf_stream_t *, uint32_t, +int cdf_read_property_info(const cdf_stream_t *, const cdf_header_t *, uint32_t, cdf_property_info_t **, size_t *, size_t *); int cdf_read_summary_info(const cdf_info_t *, const cdf_header_t *, const cdf_sat_t *, const cdf_sat_t *, const cdf_stream_t *, const cdf_dir_t *, cdf_stream_t *); -int cdf_unpack_summary_info(const cdf_stream_t *, cdf_summary_info_header_t *, +int cdf_unpack_summary_info(const cdf_stream_t *, const cdf_header_t *, cdf_summary_info_header_t *, cdf_property_info_t **, size_t *); int cdf_print_classid(char *, size_t, const cdf_classid_t *); int cdf_print_property_name(char *, size_t, uint32_t); diff --git a/ext/fileinfo/libmagic/readcdf.c b/ext/fileinfo/libmagic/readcdf.c index 117dc78..d26054e 100644 --- a/ext/fileinfo/libmagic/readcdf.c +++ b/ext/fileinfo/libmagic/readcdf.c @@ -151,14 +151,14 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, } private int -cdf_file_summary_info(struct magic_set *ms, const cdf_stream_t *sst) +cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h, const cdf_stream_t *sst) { cdf_summary_info_header_t si; cdf_property_info_t *info; size_t count; int m; - if (cdf_unpack_summary_info(sst, &si, &info, &count) == -1) + if (cdf_unpack_summary_info(sst, h, &si, &info, &count) == -1) return -1; if (NOTMIME(ms)) { @@ -256,7 +256,7 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf, #ifdef CDF_DEBUG cdf_dump_summary_info(&h, &scn); #endif - if ((i = cdf_file_summary_info(ms, &scn)) == -1) + if ((i = cdf_file_summary_info(ms, &h, &scn)) == -1) expn = "Can't expand summary_info"; free(scn.sst_tab); out4: