diff options
author | Xin LI <delphij@FreeBSD.org> | 2019-11-18 04:22:04 +0000 |
---|---|---|
committer | Xin LI <delphij@FreeBSD.org> | 2019-11-18 04:22:04 +0000 |
commit | f327c2ba2fb6ab6915a19c02db291fcdeb43840d (patch) | |
tree | f37cc1589dd2c562dd3a55363f174ac5ceee4b3a /contrib/file | |
parent | 470182bb6eef79e52f276447b9f9eb556e05fef9 (diff) | |
parent | d824749b30b5c69e76ef1eb0d13e6a6270853d32 (diff) | |
download | src-test-f327c2ba2fb6ab6915a19c02db291fcdeb43840d.tar.gz src-test-f327c2ba2fb6ab6915a19c02db291fcdeb43840d.zip |
MFV r354798:
Apply vendor fixes:
06de62c Detect multiplication overflow when computing sector position
46a8443 Limit the number of elements in a vector (found by oss-fuzz)
Requested by: wen
MFC after: 3 days
Security: CVE-2019-18218
Notes
Notes:
svn path=/head/; revision=354802
Diffstat (limited to 'contrib/file')
-rw-r--r-- | contrib/file/src/cdf.c | 27 | ||||
-rw-r--r-- | contrib/file/src/cdf.h | 1 |
2 files changed, 21 insertions, 7 deletions
diff --git a/contrib/file/src/cdf.c b/contrib/file/src/cdf.c index 556a3ff868098..bb81d6374194e 100644 --- a/contrib/file/src/cdf.c +++ b/contrib/file/src/cdf.c @@ -35,7 +35,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: cdf.c,v 1.114 2019/02/20 02:35:27 christos Exp $") +FILE_RCSID("@(#)$File: cdf.c,v 1.116 2019/08/26 14:31:39 christos Exp $") #endif #include <assert.h> @@ -53,6 +53,10 @@ FILE_RCSID("@(#)$File: cdf.c,v 1.114 2019/02/20 02:35:27 christos Exp $") #define EFTYPE EINVAL #endif +#ifndef SIZE_T_MAX +#define SIZE_T_MAX CAST(size_t, ~0ULL) +#endif + #include "cdf.h" #ifdef CDF_DEBUG @@ -405,7 +409,12 @@ cdf_read_sector(const cdf_info_t *info, void *buf, size_t offs, size_t len, const cdf_header_t *h, cdf_secid_t id) { size_t ss = CDF_SEC_SIZE(h); - size_t pos = CDF_SEC_POS(h, id); + size_t pos; + + if (SIZE_T_MAX / ss < CAST(size_t, id)) + return -1; + + pos = CDF_SEC_POS(h, id); assert(ss == len); return cdf_read(info, CAST(off_t, pos), RCAST(char *, buf) + offs, len); } @@ -415,7 +424,12 @@ cdf_read_short_sector(const cdf_stream_t *sst, void *buf, size_t offs, size_t len, const cdf_header_t *h, cdf_secid_t id) { size_t ss = CDF_SHORT_SEC_SIZE(h); - size_t pos = CDF_SHORT_SEC_POS(h, id); + size_t pos; + + if (SIZE_T_MAX / ss < CAST(size_t, id)) + return -1; + + pos = CDF_SHORT_SEC_POS(h, id); assert(ss == len); if (pos + len > CDF_SEC_SIZE(h) * sst->sst_len) { DPRINTF(("Out of bounds read %" SIZE_T_FORMAT "u > %" @@ -1013,8 +1027,9 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h, goto out; } nelements = CDF_GETUINT32(q, 1); - if (nelements == 0) { - DPRINTF(("CDF_VECTOR with nelements == 0\n")); + if (nelements > CDF_ELEMENT_LIMIT || nelements == 0) { + DPRINTF(("CDF_VECTOR with nelements == %" + SIZE_T_FORMAT "u\n", nelements)); goto out; } slen = 2; @@ -1056,8 +1071,6 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h, goto out; inp += nelem; } - DPRINTF(("nelements = %" SIZE_T_FORMAT "u\n", - nelements)); for (j = 0; j < nelements && i < sh.sh_properties; j++, i++) { diff --git a/contrib/file/src/cdf.h b/contrib/file/src/cdf.h index 2f7e554b71809..05056668fb220 100644 --- a/contrib/file/src/cdf.h +++ b/contrib/file/src/cdf.h @@ -48,6 +48,7 @@ typedef int32_t cdf_secid_t; #define CDF_LOOP_LIMIT 10000 +#define CDF_ELEMENT_LIMIT 100000 #define CDF_SECID_NULL 0 #define CDF_SECID_FREE -1 |